Неразрешенный символ при использовании функции matlab превращается в разделяемую библиотеку

Я использую MATLAB R2012A и Visual Studio 2013.

У меня есть простая функция в файле simulation.

function [ r ] = simulation(  )
  r = 42;
end

Поскольку VS2013 не поддерживается MATLAB 2012, я настроил свою версию VS в MATLAB, используя эти файлы. Затем я построил соответствующую DLL, используя:

>> mcc -v -W lib:libsim -T link:lib simulation.m
Compiler version: 4.17 (R2012a) 
Processing C:\Program Files\MATLAB\R2012a\toolbox\matlab\mcc.enc 
Processing include files... 
2 item(s) added. 
Processing directories installed with MCR... 
The file mccExcludedFiles.log contains a list of functions excluded from the CTF archive. 
1 item(s) added. 
Generating MATLAB path for the compiled application... 
Created 41 path items. 
Begin validation of MEX files: Wed Apr 15 13:55:43 2015 
End validation of MEX files: Wed Apr 15 13:55:43 2015 
Parsing file "C:\Users\aaptel\Documents\MATLAB\simulation.m" 
    (Referenced from: "Compiler Command Line"). 
Parsing file "C:\Program Files\MATLAB\R2012a\toolbox\compiler\deploy\deployprint.m" 
    (Referenced from: "Compiler Command Line"). 
Parsing file "C:\Program Files\MATLAB\R2012a\toolbox\compiler\deploy\printdlg.m" 
    (Referenced from: "Compiler Command Line"). 
Deleting 0 temporary MEX authorization files. 
Generating file "libsim.h". 
Generating file "libsim.c". 
Generating file "libsim.exports". 
Generating file "C:\Users\aaptel\Documents\MATLAB\readme.txt". 
Executing command: ""C:\Program Files\MATLAB\R2012a\bin\mbuild"  -O -v -output "libsim" "libsim.c" "libsim.exports" -link shared"-> Default options filename found in C:\Users\aaptel\AppData\Roaming\MathWorks\MATLAB\R2012a 
---------------------------------------------------------------- 
->    Options file           = C:\Users\aaptel\AppData\Roaming\MathWorks\MATLAB\R2012a\compopts.bat 
->    COMPILER               = cl 
->    Compiler flags: 
         COMPFLAGS           = -MD -c -Zp8 -GR -EHsc- -Zc:wchar_t- -W3 -nologo -I"C:\PROGRA~1\MATLAB\R2012a\extern\include\win64" -DMSVC -DIBMPC /D_CRT_SECURE_NO_DEPRECATE 
         OPTIMFLAGS          = -O2 -DNDEBUG 
         DEBUGFLAGS          = -Z7 
         arguments           =  
         Name switch         = /Fo 
->    Pre-linking commands   =  
->    LINKER                 = link 
->    Link directives: 
         LINKFLAGS           =  /MACHINE:AMD64 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /LIBPATH:"C:\PROGRA~1\MATLAB\R2012a\extern\lib\win64\microsoft" /nologo /manifest /manifestfile:"libsim.msvc.manifest" mclmcrrt.lib   /dll /implib:"libsim.lib" /def:"C:\Users\aaptel\AppData\Local\Temp\mbuild_F85T7Q\templib.def" 
         LINKFLAGSPOST       =  
         Name directive      = /out:"libsim.dll" 
         File link directive =  
         Lib. link directive =  
         Rsp file indicator  = @ 
->    Resource Compiler      = rc /fo ".res" 
->    Resource Linker        =  
---------------------------------------------------------------- 


--> cl  -MD -c -Zp8 -GR -EHsc- -Zc:wchar_t- -W3 -nologo -I"C:\PROGRA~1\MATLAB\R2012a\extern\include\win64" -DMSVC -DIBMPC /D_CRT_SECURE_NO_DEPRECATE /FoC:\Users\aaptel\AppData\Local\Temp\mbuild_F85T7Q\libsim.obj -IC:\PROGRA~1\MATLAB\R2012a\extern\include -IC:\PROGRA~1\MATLAB\R2012a\simulink\include -O2 -DNDEBUG libsim.c 

libsim.c 

--> type C:\Users\aaptel\AppData\Local\Temp\mbuild_F85T7Q\mbuild_tmp.exports | "C:\PROGRA~1\MATLAB\R2012a\sys\perl\win32\bin\perl.exe" -e "print \"LIBRARY libsim.dll\nEXPORTS\n\"; while (<>) {print;}" > "C:\Users\aaptel\AppData\Local\Temp\mbuild_F85T7Q\templib.def" 

    Contents of C:\Users\aaptel\AppData\Local\Temp\mbuild_F85T7Q\mbuild_tmp.rsp: 
  C:\Users\aaptel\AppData\Local\Temp\mbuild_F85T7Q\libsim.obj 


--> link /out:"libsim.dll"  /MACHINE:AMD64 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /LIBPATH:"C:\PROGRA~1\MATLAB\R2012a\extern\lib\win64\microsoft" /nologo /manifest /manifestfile:"libsim.msvc.manifest" mclmcrrt.lib   /dll /implib:"libsim.lib" /def:"C:\Users\aaptel\AppData\Local\Temp\mbuild_F85T7Q\templib.def"  @C:\Users\aaptel\AppData\Local\Temp\mbuild_F85T7Q\mbuild_tmp.rsp   

   Création de la bibliothèque libsim.lib et de l'objet libsim.exp 

--> "if exist C:\Users\aaptel\AppData\Local\Temp\mbuild_F85T7Q\templib.def del C:\Users\aaptel\AppData\Local\Temp\mbuild_F85T7Q\templib.def" 


--> mt.exe -outputresource:"libsim.dll";2 -manifest "libsim.msvc.manifest" 

Microsoft (R) Manifest Tool version 6.3.9600.17298  
Copyright (c) Microsoft Corporation 2012.   
All rights reserved.  

--> del "libsim.msvc.manifest"

Теперь у меня есть следующие файлы:

  • libsim.dll
  • libsum.exp
  • libsim.c
  • libsim.exports
  • libsim.h

Я установил 64-битную среду исполнения MATLAB для MATLAB R2012a.

Я создал новое решение C++ в VS и добавил libsim.lib зависимость, наряду с Matlab lib/include Dir.

Вот мой основной файл cpp:

#include <cstdio>
#include <libsim.h>

int main(void)
{
    double v = 42;
    libsimInitialize();
    printf("%d\n", v);
    libsimTerminate();
    return 0;
}

Флаги компилятора:

/GS /analyze- /W3 /Zc:wchar_t /I"C:\Users\aaptel\Documents\Visual Studio 2013\Projects\CppTest\CppTest\Include\matlab" /ZI /Gm /Od /sdl /Fd"Debug\vc120.pdb" /fp:precise /D "_MBCS" /errorReport:prompt /WX- /Zc:forScope /RTC1 /Gd /Oy- /MDd /Fa"Debug\" /EHsc /nologo /Fo"Debug\" /Fp"Debug\CppTest.pch" 

Флаги компоновщика:

/OUT:"C:\Users\aaptel\Documents\Visual Studio 2013\Projects\CppTest\Debug\CppTest.exe" /MANIFEST /NXCOMPAT /PDB:"C:\Users\aaptel\Documents\Visual Studio 2013\Projects\CppTest\Debug\CppTest.pdb" /DYNAMICBASE "kernel32.lib" "user32.lib" "gdi32.lib" "winspool.lib" "comdlg32.lib" "advapi32.lib" "shell32.lib" "ole32.lib" "oleaut32.lib" "uuid.lib" "odbc32.lib" "odbccp32.lib" "libsim.lib" /DEBUG /MACHINE:X86 /INCREMENTAL /PGD:"C:\Users\aaptel\Documents\Visual Studio 2013\Projects\CppTest\Debug\CppTest.pgd" /MANIFESTUAC:"level='asInvoker' uiAccess='false'" /ManifestFile:"Debug\CppTest.exe.intermediate.manifest" /ERRORREPORT:PROMPT /NOLOGO /LIBPATH:"C:\Users\aaptel\Documents\Visual Studio 2013\Projects\CppTest\CppTest\Lib\matlab" /TLBID:1

libsim.lib там, Lib\matlab а также Include\matlab пути имеют копию библиотек времени выполнения и библиотек Matlab.

Но. Это. не делает. долбанные. компиляции.

1>Source.obj : error LNK2019: symbole externe non résolu _libsimInitialize référencé dans la fonction _main
1>Source.obj : error LNK2019: symbole externe non résolu _libsimTerminate référencé dans la fonction _main
1>C:\Users\aaptel\Documents\Visual Studio 2013\Projects\CppTest\Debug\CppTest.exe : fatal error LNK1120: 2 externes non résolus

Обратите внимание, как компилятор ищет символ с префиксом подчеркивания. Если вы посмотрите на символ в файле lib с помощью DUMPBIN, то увидите, что у него нет префикса ( полный вывод DUMPBIN):

Dump of file libsim.lib

File Type: LIBRARY

Archive member name at 8: /               
552CE345 time/date Tue Apr 14 11:52:05 2015
         uid
         gid
       0 mode
     190 size
correct header end

    15 public symbols

      3AA __IMPORT_DESCRIPTOR_libsim
      5D0 __NULL_IMPORT_DESCRIPTOR
      706 libsim_NULL_THUNK_DATA
      85E __imp_libsimInitialize
      85E libsimInitialize
      8CA __imp_libsimInitializeWithHandlers
      8CA libsimInitializeWithHandlers
      9B4 __imp_libsimTerminate
      9B4 libsimTerminate
      942 __imp_libsimPrintStackTrace
      942 libsimPrintStackTrace
      A8A __imp_mlxSimulation
      A8A mlxSimulation
      A20 __imp_mlfSimulation
      A20 mlfSimulation

Почему это не работает и как я могу вызвать мою функцию Matlab из C++?

1 ответ

Решение

Хорошо, получается, что проект VS был 32-битным, но lib / dll, сгенерированный MATLAB, был 64-битным. Переключив проект VS на x64, он скомпилирован.

VS, кажется, молча игнорирует связывание 32-битного исполняемого файла с 64-битными библиотеками

Также см. Следующий пост на сайте mathworks QA:

http://www.mathworks.com/matlabcentral/answers/203699-how-do-i-call-standalone-matlab-shared-library-built-with-mcc-from-c

Другие вопросы по тегам