Ошибка проверки времени выполнения # 0: Использование C-экспортов из MinGW dll в VC ++ (или: Использование libclang MinGW build в приложении VC ++) - PullRequest
0 голосов
/ 12 февраля 2012

Этот вопрос касается использования 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 ??

...