MATLAB Answers

0

MEX: C++ function doesn't find DLL when called from Matlab using mexFunction

Asked by Nicolai Kern on 29 Jan 2018
Latest activity Commented on by Nicolai Kern on 29 Jan 2018
I have to call functions of a 32-Bit-DLL from Matlab to control a positioner system for Antenna Measurements. Since I can’t import the DLL functions properly using the “loadlibrary” command (some forum contributions suggest because 32-Bit DLLs won’t work with 64-Bit Matlab), I want to write a C++ controller class that loads the DLL once at instantiation and then through its methods acts as an interface to Matlab. For that purpose I modified the class wrapper that can be found on Mathworks File Exchange platform ( https://de.mathworks.com/matlabcentral/fileexchange/38964-example-matlab-class-wrapper-for-a-c++-class ). The C++ class I've implemented loads the 32-Bit DLL, using the LoadLibrary() command. Problem:
  • I tested the functionality of this C++ controller class by writing a short console application in Microsoft Visual Studio 2017, and it work's fine - in particular, the DLL is loaded properly.
  • When I add the class wrapper, compile it with MEX (compiler: Microsoft Windows SDK 7.1 (C++)) and call the class method that loads the DLL, the program principally works fine, too (issues no error) - but it doesn't find the DLL.
My C++ class PositionerController has a loadCanApiDll function, which calls LoadLibrary to load the DLL:
// Load CanApi DLL
bool PositionerController::loadCanApiDll(LPCTSTR dllPath)
{
hCanApi = LoadLibrary(dllPath);
if (hCanApi != NULL)
{
return TRUE;
}
else
{
return FALSE;
}
}
In the mexFunction, the handle held in the corresponding Matlab class is used to find the C++ object. Then, the loadCanApiDll function is called from the mexFunction on the previously found PositionerController instance, posCtrl:
// Get class instance pointer
PositionerController *posCtrl = convertMat2Ptr<PositionerController>(prhs[1]);
// Load DLL
if (!strcmp("LoadDLL", cmd)) {
// Get dllFolder
dllPath = mxArrayToString(prhs[2]);
dllPath = "C:\\Users\\(User Name)\\Documents\\MATLAB\\Ansteuerung C++\\CanApi.dll";
// Call loadCanApiDll
if (posCtrl->loadCanApiDll(dllPath)) {
// success --> return 1 to Matlab
plhs[0] = mxCreateDoubleScalar(1);
return;
}
else {
// failed --> return 0 to Matlab
plhs[0] = mxCreateDoubleScalar(0);
return;
}
}
The dllPath is hard-encoded for testing purposes to make sure that it's no Matlab/ C++ data conversion issue. In Matlab, I have a PositionerController.m class and a very basic script just creating an instance of the C++ class and calling its various methods:
%%Create instance of PositionerController matlab class
posCtrl = PositionerController();
%%Call LoadDll fct.
returnVal = posCtrl.LoadDll(dllPath);
%%Call mctl_Initialize fct.
returnVal = posCtrl.mctl_Initialize(iniFilePath);
%%Call mctl_Reset fct.
returnVal = posCtrl.mctl_Reset();
%%Call mctl_Reference fct.
returnVal = posCtrl.mctl_Reference(dwAxis);
The mexFunction and Class definition C++ file both compile without an error. From the return values I also can infer that the mexFunction and the loadCanApiDll class method principally both work fine - except the fact, that LoadLibrary() doesn't find the DLL.
Does anybody have an idea, why the LoadLibrary() C++ command works when it is used in a test program written and compiled using Microsoft Visual Studio 2017, but fails to do so when it is compiled and called from within Matlab using Microsoft Windows SDK 7.1 (C++) and MEX?

  1 Comment

Just tried to use a arbitrary 64-Bit DLL, and the program found the DLL handle. Are the Matlab compilers in general unable to deal with 32-Bit DLLs? And if so, is there any reasonable workaround?

Sign in to comment.

Tags

0 Answers