调用 API 函数时出现 ESP 错误?

Posted

技术标签:

【中文标题】调用 API 函数时出现 ESP 错误?【英文标题】:ESP Error when I call an API function? 【发布时间】:2009-12-19 16:05:13 【问题描述】:

平台:win32,语言:c++

我在调用我声明的导入函数时收到此错误:

运行时检查失败 #0 - ESP 的值未正确保存 通过函数调用。这是 通常是调用函数的结果 用一个调用约定声明 使用声明的函数指针 不同的调用约定。

这是我使用的代码:

int LoadSongFromFile(int module);
typedef int (CALLBACK* loadSongT)(LPCTSTR);

//...

HINSTANCE dllHandle = NULL;
loadSongT loadSongPtr = NULL;

dllHandle = LoadLibrary(L"miniFMOD.dll");
loadSongPtr = (loadSongT)GetProcAddress(dllHandle,"SongLoadFromFile");

int songHandle = loadSongPtr(L"C:\b.xm");

我试图调用的函数是 SongLoadFromFile,它需要一个参数(在 C# 中它是字符串,所以我假设它在 C++ 中是 LPCTSTR)并返回一个 int 值。

谁能检查我做错了什么?

附: songHandle 得到一个奇怪的负值 -858993460

这就是我可以从 C# 调用该函数的方式:

[DllImport("MiniFMOD.dll")] public static extern int SongLoadFromFile(string name);

附: 2 : 使用 *typedef int (__cdecl loadSongT)(char);* 不会返回错误,但 songHandle 显示为 0。

miniFMOD.dll 是一个非托管库

【问题讨论】:

【参考方案1】:

我认为其他人误解了这个问题。在我看来,minifmod.dll 是一个导出名为 SongLoadFromFile 的函数的本机库。调用它的现有代码是托管代码 (C#),它使用 DllImport 调用本机 DLL 中的函数。从我可以通过几次 Google 搜索收集到的少量信息来看,它似乎应该声明如下:

typedef int (__cdecl * SongLoadFromFileT)(const char*);

重要的是,它是 __cdecl 调用约定,它采用 ANSI 字符串而不是 Unicode 字符串。

顺便说一句,我觉得奇怪的是,我在 minifmod.dll 上找不到任何东西,除了俄罗斯网站上的一些论坛帖子和这个人提出的一些 SO 问题。我可以在 minifmod 上找到的唯一“合法”信息是一个具有类似功能的小型静态库。我想知道 minifmod.dll 是否是静态库的某种商业化版本;至少这可以解释为什么没有太多关于它的公开文档。

啊,我找到了;它是 minifmod (http://www.cobans.net/minifmod.php) 的 Delph 端口。

【讨论】:

你给我的例子没有触发任何错误,但是 songHandle 仍然是 0 意味着文件不存在或者调用函数时出了问题 您传递的是 ANSI 字符串吗?您的示例代码不是。此外,您没有转义反斜杠字符;路径应该是“C:\\b.xm”。如果出现问题,Win32 库通常会调用 SetLastError() 并显示发生的任何错误代码;你可以调用 GetLastError() 来查看它是否被设置。除此之外,我不是通灵者,没有文件就无法提供任何帮助。您可以随时尝试运行文件监视器以查看它实际尝试访问的文件(如果有),或者如果您不顾一切,您可以进入汇编代码。 OMFG ,转义反斜杠工作。我爱你! 这就是它一直返回 0 的原因,因为那个反斜杠是因为它无法检索文件【参考方案2】:

您需要确保在函数指针原型中指定正确的调用约定(“CALLBACK”可能是错误的选择)。

【讨论】:

你能详细解释一下吗?【参考方案3】:

调用代码使用的调用约定与被调用函数的调用约定不匹配。见this very similar question。您需要打开定义该函数的标头(应该与您尝试使用的库一起提供),查看约定并相应地更改函数指针声明。

【讨论】:

那不一定是 WINAPI,可能是任何东西。您需要查看库文档以找到要使用的约定。 没有文档,但是知道 C# 函数的语法有帮助吗? 直到现在才注意到“C#”。甚至不确定从托管 DLL 调用函数是否可以在不使用某些互操作的情况下工作。您是否搜索过如何从非托管代码中调用托管代码?在这里我帮不了你,只能说我们为了同样的目的把C#库暴露给COM,并通过COM来使用。 这不是我的意思。 dll 是用 c++ 编写的,但我知道如何从 c# 中使用它: [DllImport("MiniFMOD.dll")] public static extern int SongLoadFromFile(string name);我没有 dll 的任何标题或文档 使用 __cdecl 不会返回任何错误,但 songHandle 出现为 0

以上是关于调用 API 函数时出现 ESP 错误?的主要内容,如果未能解决你的问题,请参考以下文章

为啥调用 API 时出现 CORS 错误

消息:尝试访问 aws gateway api 时出现“内部服务器错误”

从 Angular Js(Java Web)调用 API 时出现 CORS 错误

通过 SSL 调用 Web Api 时出现 403 禁止错误

尝试通过android调用JSON api时出现无效请求错误

使用令牌标头进行后 API 调用时出现 405 错误