Этот вопрос касается использования C-функций из библиотеки MinGW в VC ++ проекте, который завершается ошибкой: Ошибка проверки времени выполнения # 0 .
Я успешно собрал clang и, что более важно, libclang, используя MinGW (чтобы иметь libclang.dll, которая использует стандартную библиотеку MinGW).
Мое приложение ранее использовало VC ++ - сборку libclang, которую я теперь хочу обменять со сборкой MinGW.
Для этого я создал def-файл, а затем импортировал библиотеку из dll-файла MinGW:
dlltool -z libclang.def --export-all-symbol libclang.dll
dlltool -d libclang.def -l libclang.lib
Перед созданием библиотеки импорта я изменил def-файл, чтобы он содержал только важные функции clang, которые были объявлены с использованием extern "C" . Вот небольшая выдержка:
LIBRARY libclang.dll
EXPORTS
clang_CXCursorSet_contains @ 50006
clang_CXCursorSet_insert @ 50007
clang_CXXMethod_isStatic @ 50008
clang_CXXMethod_isVirtual @ 50009
clang_Cursor_getTranslationUnit @ 50010
Используя dll MinGW и новую библиотеку импорта, я теперь могу успешно скомпилировать свое приложение. Он работает, и я на самом деле могу использовать некоторые функции, такие как "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);
На самом деле я понятия не имею, почему это работает для некоторых функций, а не для других!
Большое спасибо!
[Update]
Для любителей сборки приведу пример сборки, которая приводит к сбою. Вызов 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.
Большой вопрос, для обоих вызовов функций, которые принимают один и тот же параметр, почему это «добавить esp, 4» после вызова clang_getNumDiagnostics, но «добавить esp, 8» при вызове clang_getTranslationUnitCursor ??