How do I call standalone MATLAB shared library (built with mcc) from C?

4 visualizzazioni (ultimi 30 giorni)
I'm using MATLAB R2012A and Visual Studio 2013.
I have a simple function in a simulation.m file.
function [ r ] = simulation( )
r = 42;
end
Since VS2013 is not supported by MATLAB 2012 I've setup my version of VS in MATLAB using these files. I've then built the corresponding dll using:
>> 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"
I now have the following files:
  • `libsim.dll`
  • `libsum.exp`
  • `libsim.c`
  • `libsim.exports`
  • `libsim.h`
I've created a new C solution in VS and added the `libsim.lib` dependency, along with the matlab lib/include dir.
Here is my main.c file:
#include <stdio.h>
#include "libsim.h"
#include "matrix.h"
void display(const mxArray* in)
{
size_t i = 0, j = 0;
size_t r = 0, c = 0;
double *data;
/* Get the size of the matrix */
r = mxGetM(in);
c = mxGetN(in);
/* Get a pointer to the double data in mxArray */
data = mxGetPr(in);
/* Loop through the data and display the same in matrix format */
for (i = 0; i < c; i++){
for (j = 0; j < r; j++){
printf("%4.2f\t", data[j*c + i]);
}
printf("\n");
}
printf("\n");
}
int main(void)
{
int err = 0;
if (!mclInitializeApplication(NULL, 0))
{
fprintf(stderr, "Could not initialize the application.\n");
err = -1;
goto lb_out1;
}
if (!libsimInitialize()) {
fprintf(stderr, "Could not initialize the library.\n");
err = -2;
goto lb_out2;
}
mxArray* out = NULL;
mlfSimulation(1, &out);
display(out);
mxDestroyArray(out);
libsimTerminate();
lb_out2:
mclTerminateApplication();
lb_out1:
system("pause");
return 0;
}
It compiles fine once you're sure the compiler is targeting x64.
1> Compilateur d'optimisation Microsoft (R) C/C++ version 18.00.31101 pour x64
1> Copyright (C) Microsoft Corporation. Tous droits réservés.
1>
1> cl /c /I"C:\Program Files\MATLAB\MATLAB Compiler Runtime\v717\extern\include" /Zi /W3 /WX- /sdl /Od /D WIN32 /D _DEBUG /D _CONSOLE /D _LIB /D _UNICODE /D UNICODE /Gm /EHsc /RTC1 /MDd /GS /fp:precise /Zc:wchar_t /Zc:forScope /Fo"x64\Debug\\" /Fd"x64\Debug\vc120.pdb" /Gd /TC /errorReport:prompt main.c
1>
1> main.c
1> Microsoft (R) Incremental Linker Version 12.00.31101.0
1> Copyright (C) Microsoft Corporation. All rights reserved.
1>
1> "/OUT:C:\Users\aaptel\Documents\Visual Studio 2013\Projects\CppTest\x64\Debug\CTest.exe" /INCREMENTAL "/LIBPATH:C:\Program Files\MATLAB\MATLAB Compiler Runtime\v717\extern\lib\win64\microsoft" 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 mclmcrrt.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /MANIFEST "/MANIFESTUAC:level='asInvoker' uiAccess='false'" /manifest:embed /DEBUG "/PDB:C:\Users\aaptel\Documents\Visual Studio 2013\Projects\CppTest\x64\Debug\CTest.pdb" /SUBSYSTEM:CONSOLE /TLBID:1 /DYNAMICBASE /NXCOMPAT "/IMPLIB:C:\Users\aaptel\Documents\Visual Studio 2013\Projects\CppTest\x64\Debug\CTest.lib" /MACHINE:X64 x64\Debug\main.obj
1> CTest.vcxproj -> C:\Users\aaptel\Documents\Visual Studio 2013\Projects\CppTest\x64\Debug\CTest.exe
See the libsim.lib and mclmcrrt.lib? OK.
Now when I run the exe, I get an error about a missing DLLs, so I copied the one mentioned in the error message in the exe directory and tried again. The DLL (libmx.dll) was somewhere in the MATLAB Compiler directory (C:\Program Files\MATLAB\MATLAB Compiler Runtime\v717\bin\win64). Now when I run it again same error, different DLL. Again, I copy it from the MATLAB Compiler directory. I did this for 4 or 5 DLLs then got fed up with it and copied all the DLLs that (about 500MB of freaking dlls files).
Ok. Now when I run the program, I get this:
Locale initialization failed in opcore with status code: 2
And the console closes immediately. I've tried to step with the debugger: the program crashes in libsimInitialize() and I can't step into it.
NOW WHAT?? Why is this so hard?
What DLLs are actually needed for the program to work without installing MATLAB?

Risposta accettata

aaptel
aaptel il 17 Apr 2015
Ok so the only needed dll in the exe directory is libsim.dll. My first test was using both libsim.dll and mclmcrrt7_17.dll. It's mclmcrrt7_17.dll that was causing all the trouble.
libsim.dll automatically looks for the runtime dependency in the MATLAB Compiler Redistributable directory (which must be installed on the client library). But it looks first in the current directory.
My guess is redistribuable dlls are expecting to be loaded from the redistributable directory. Since I've copied them to the exe directory, it was loading them from there instead which doesn't work.
So, you only need to:
  • install the right MATLAB redistributable
  • put the dll produced by MATLAB (libsim.dll in this case) in the exe directory

Più risposte (1)

Philip Caplan
Philip Caplan il 17 Apr 2015
Based on the solution found in the following link, this sounds like it may be related to whether you are using Visual Studio or MATLAB in 32 or 64 bits:
Can you try copying the 32-bit DLL's needed by your application to the exe directory you mentioned?

Categorie

Scopri di più su MATLAB Compiler in Help Center e File Exchange

Prodotti

Community Treasure Hunt

Find the treasures in MATLAB Central and discover how the community can help you!

Start Hunting!

Translated by