0

我在 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文件和头文件有冲突吗?

4

1 回答 1

2

头文件根本没有指定调用约定。所以现在你依赖于编译器的默认值。它在 MSVC++ IDE 中使用 Project > Properties > C/C++ > Advanced > "Calling Convention" 设置进行配置。正如您所期望的那样,默认值为 /Gd,将其更改为 /Gz 作为 Q&D 修复程序并不少见。

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

如果您没有源代码,那么您将无法更改它。stdcall 没有什么特别的问题,它是 Windows 上预期的互操作默认值。

于 2018-08-13T10:53:05.183 回答