此问题是关于在 VC ++ 项目中使用来自MinGW dll的C函数,该项失败并出现以下错误:运行时检查失败# 0
我使用MinGW成功构建了clang,更重要的是libclang(使用了一个使用MinGW标准库的libclang.dll)。
我的应用程序以前使用的是VC ++ - libclang的构建,我现在想要与MinGW构建交换。
为此,我创建了一个def文件,然后从MinGW dll文件创建了一个导入库:
dlltool -z libclang.def --export-all-symbol libclang.dll
dlltool -d libclang.def -l libclang.lib
在创建导入库之前,我更改了def文件,因此它只包含使用 extern“C”声明的重要clang函数。这是一个小摘录:
LIBRARY libclang.dll
EXPORTS
clang_CXCursorSet_contains @ 50006
clang_CXCursorSet_insert @ 50007
clang_CXXMethod_isStatic @ 50008
clang_CXXMethod_isVirtual @ 50009
clang_Cursor_getTranslationUnit @ 50010
使用MinGW dll和新的导入库,我现在可以成功编译我的应用程序。它运行,我实际上可以使用一些函数,如“clang_createIndex”,但每当我到“clang_getTranslationUnitCursor”我得到一个:
运行时检查失败#0 - ESP的值未在函数调用中正确保存。这通常是调用使用一个调用约定声明的函数的结果,函数指针使用不同的调用约定声明。
Clang 的Index.h中的函数(因此不受我的控制)声明如下:
#ifdef _MSC_VER
#ifdef _CINDEX_LIB_
#define CINDEX_LINKAGE __declspec(dllexport)
#else
#define CINDEX_LINKAGE __declspec(dllimport)
#endif
#else
#define CINDEX_LINKAGE
#endif
CINDEX_LINKAGE CXCursor clang_getTranslationUnitCursor(CXTranslationUnit);
我实际上不知道,为什么它适用于某些功能而不适用于其他功能!
非常感谢!
[更新]
对于装配爱好者来说,这是导致崩溃的一些示例装配。对clang_getNumDiagnostics的调用有效,调用clang_getTranslationUnitCursor在最后一行失败,当调用__RTC_CheckEsp时 - 这是检查ESP正确性的函数
// call to clang_getNumDiagnostics(TU); - works!
5AF3EFAB mov esi,esp
5AF3EFAD mov eax,dword ptr [ebp-30h]
5AF3EFB0 push eax
5AF3EFB1 call dword ptr [__imp__clang_getNumDiagnostics (5AF977E0h)]
5AF3EFB7 add esp,4
5AF3EFBA cmp esi,esp
5AF3EFBC call @ILT+7135(__RTC_CheckEsp) (5AF16BE4h)
// call to clang_getTranslationUnitCursor(TU); - fails!
5AF3EFC1 mov esi,esp
5AF3EFC3 mov eax,dword ptr [ebp-30h]
5AF3EFC6 push eax
5AF3EFC7 lea ecx,[ebp-234h]
5AF3EFCD push ecx
5AF3EFCE call dword ptr [__imp__clang_getTranslationUnitCursor (5AF9780Ch)]
5AF3EFD4 add esp,8
5AF3EFD7 cmp esi,esp
5AF3EFD9 call @ILT+7135(__RTC_CheckEsp) (5AF16BE4h)
在调用clang_getTranslationUnitCursor期间,esp将增加4。 最大的问题是,对于两个采用相同参数的函数调用,为什么在调用clang_getNumDiagnostics之后“添加esp,4”,但在调用clang_getTranslationUnitCursor时“添加esp,8”