PInvoke 的意外调用约定

Unexpected calling convention for PInvoke

我在 dll 及其头文件中有一个库,但我没有它的源代码。 我需要使用 pinvoke 从 C# 调用此非托管代码,但在设置调用约定时遇到问题。头文件如下所示:

#ifdef EVOLIB_EXPORTS
#define EVOLIB_API __declspec(dllexport)
#else
#define EVOLIB_API __declspec(dllimport)
#endif
extern EVOLIB_API int ConvertRVBtoK(char *FileNameIn, char *FileNameOut,int ColorSmooth,int BlackMode);

我认为 ConvertRVBtoK 调用约定必须是 __cdecl 因为这是默认的 c/c++ 调用约定。但是,当我使用 undname.exe 实用程序检查装饰名称(“?ConvertRVBtoK@@YGHPAEJJJ0E@Z”)时,结果显示 __stdcall 作为调用约定。为什么?是不是dll文件和头文件有冲突?

头文件根本没有指定调用约定。所以现在你依赖于编译器的默认值。它在 MSVC++ IDE 中配置为项目 > 属性 > C/C++ > 高级 > "Calling Convention" 设置。正如您所期望的那样,默认值为 /Gd,看到它更改为 /Gz 作为 Q&D 修复程序并不是很不寻常。

小心更改它,您可能会破坏其他在互操作代码中依赖 stdcall 的程序。请注意,您之前询问过 pascal 约定,即 32 位代码中的 stdcall。在头文件中明确说明,因此您不依赖于编译器默认值也不会受到伤害。

如果您没有源代码,那么您将无法更改它。 stdcall 没有什么特别的问题,它是 Windows.

上预期的互操作默认值