我在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文件和头文件之间有冲突吗?
答案 0 :(得分:2)
头文件根本没有指定调用约定。因此,现在您取决于编译器的默认设置。在MSVC ++ IDE中使用“项目”>“属性”>“ C / C ++”>“高级”>“调用约定”设置进行配置。正如您所期望的那样,默认值为/ Gd,将其更改为/ Gz作为Q&D修复并不罕见。
要小心更改它,您可能会破坏其他依赖于互操作代码中stdcall的程序。请注意,您之前曾询问过pascal
约定,即32位代码中的stdcall。在头文件中显式表示,因此您不必依赖编译器的默认值也不会受到损害。
如果没有源代码,则无法更改它。 stdcall没什么特别的问题,它是Windows上预期的互操作默认值。