使用变成共享库的 matlab 函数时无法解析的符号

Unresolved symbol while using a matlab function turned into a shared library

我正在使用 MATLAB R2012A 和 Visual Studio 2013。

我在 simulation.m 文件中有一个简单的函数。

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

由于 MATLAB 2012 不支持 VS2013,因此我使用 these files 在 MATLAB 中设置了我的 VS 版本。 然后我使用以下方法构建了相应的 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"

我现在有以下文件:

我已经安装了 64bit MATLAB runtime for MATLAB R2012a

我在 VS 中创建了一个新的 C++ 解决方案并添加了 libsim.lib 依赖项,以及 matlab lib/include 目录。

这是我的主要 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\matlabInclude\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

注意编译器如何查找带有下划线前缀的符号。如果您使用 DUMPBIN 查看 lib 文件中的符号,您会发现它们没有前缀 (full DUMPBIN output):

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

为什么它不起作用?如何从 C++ 调用我的 matlab 函数?

好的,原来 VS 项目是 32 位的,而 MATLAB 生成的 lib/dll 是 64 位的。通过将VS项目切换到x64,它编译。

VS 似乎默默地忽略了将 32 位可执行文件链接到 64 位库

另请参阅 mathworks QA 网站上的后续 post:

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