Matlab Runtime problems when calling wrapper DLL
5 views (last 30 days)
Show older comments
Greetings!
Facing the following challenge. I am working on a collaborative effort to call Matlab DLL functions that need to be wrapped in a shell DLL, so that a program (i.e. LabVIEW) can import and make calls to its functions. As background info, the Matlab developer and myself have the same development and runtime versions of Matlab. We are provided with a series of individual wrapped DLLs that get imported for use in another application. Now, on the side that uses the Matlab Runtime, while the first used DLL function that gets called and processed executes correctly, a subsequent call to any other DLLs' function won't execute. The presumption is that the initial function that ran had grabbed and hold on to the runtime resources, making its use by other DLL functions unavailable. Now, why do I say this? The following is a running scenarios could explain:
Scenario A
DLL#1 Function called - Executes correctly (outcome is verified correct)
then DLL#2 Function called - Does not execute
then DLL#1 Function called (again) - Executes correclty.
The fact that the second call attempt on DLL#1 function was able to re-run while DLL#2 function was not, makes believe that the runtime is still dancing with DLL#1 and unable to work with any other DLL function.
Scenario B (For this, I've closed all programs to start fresh with no dependancies in use anywhere)
DLL#2 Function called - Executes correctly (outcome is verified correct)
then DLL#1 Function called - Does not execute
DLL#2 Function calles (again) - Executes correclty. The same as in scenario A is observed. So the first DLL function that uses the Matlab Runtime gets to hold it.
Needles to say that I am not a Matlab user. However, I share below the .c files for the wrapper DLLs I refer to above. There are very similar, side by side they both have:
a isMCRrunning() function, that checks if the Runtime is up, if not, it initializes it.
a wrapped main function wmlfABCDEF(some arguments)
a terminateMCR(), to kill the Runtime
Now, even if the terminateMCR isn't called or used, the sceanrios A and B above hold. If the terminateMCR is used, no function will ever be able to run (unable the program is closed, but closing everything is counterproductive). What could be the reason why the Runtime marries with the first called DLL function and completely overlooks any other DLL function that needs to use it as well. Can something in the code below be spotted as being the actual reason?
Thanks to anyon that could share some thoughts.
-JR
=======================================================DLL#1 Wrapper ===========================================================
#include<stdio.h>
#include "POWERMONITOR.h"
#include "matrix.h"
/* Global flag to indicate if MCR is initialized */
int MCRrunning=FALSE;
/* Each function wrapper should call this function first */
int isMCRrunning(){
int result;
if(MCRrunning){
/*We have already initialized the MCR and initialized the MATLAB library DLL in a previous call */
return TRUE;
}
else{
/* Start the MCR */
mclmcrInitialize();
result = mclInitializeApplication(NULL, 0);
if (!result){
printf("Failed to initialize MCR\n");
return result;
}
/* Initialize the MATLAB generated DLL */
result = POWERMONITORInitialize();
if(!result){
printf("Failed to initialize Library\n");
return result;
}
else{
MCRrunning=TRUE;
return result;
}
}
}
/*Function to terminate the MCR*/
void terminateMCR(void) {
MCRrunning=FALSE;
POWERMONITORTerminate();
mclTerminateApplication();
//Sometimes, repeated initialization and termination of an application may cause the application to hang. To avoid this, call mclInhibitShutdown() immediately after calling mclInitializeApplication(). For example:
//mclInhibitShutdown();
}
/*Function that wraps the top-level m function and converts C types to/from the MATLAB mxArray type*/
//int wmlfPOWERMONITOR(int* c2m_array, int size, char* message){
int wmlfPOWERMONITOR(int* c2m_array, int size, char* SerialNum, char* FilePath, char* message){
/*Define variables*/
int nargout=1;
int result=1;
/* Start MCR, load library if not done already */
int returnval=isMCRrunning();
if(!returnval){
return returnval;
}
/* Pointers to MATLAB data */
// container for the output 'output' of size 1 (is an integer)
// need to create an mxArray to use as a container for output
mxArray *msg=mxCreateString(message);
mxArray *output=mxCreateDoubleMatrix(size, size, false);
mxArray *SN=mxCreateString(SerialNum);
mxArray *FP=mxCreateString(FilePath);
/* Convert C data to MATLAB data */
// translating 'c2m_array' to 'output'
memcpy(mxGetPr(output), c2m_array, size*size*sizeof(int));
/*Call the M function*/
// result says if it passed or not
// passing in pointer 'output' by reference (&)
//result=mlfPOWERMONITOR(nargout, &output, msg);
result=mlfPOWERMONITOR(nargout, &output, SN, FP, msg);
/* Convert returned MATLAB data to C data */
// ex. memcpy(dest, src, size)
memcpy(c2m_array, mxGetPr(output), size*size*sizeof(int));
/* Clean up MATLAB variables */
mxDestroyArray(msg);
mxDestroyArray(output);
mxDestroyArray(SN);
mxDestroyArray(FP);
return result;
}
=======================================================DLL#2 Wrapper ===========================================================
#include<stdio.h>
#include "POWERMONITOR.h"
#include "matrix.h"
/* Global flag to indicate if MCR is initialized */
int MCRrunning=FALSE;
/* Each function wrapper should call this function first */
int isMCRrunning(){
int result;
if(MCRrunning){
/*We have already initialized the MCR and initialized the MATLAB library DLL in a previous call */
return TRUE;
}
else{
/* Start the MCR */
mclmcrInitialize();
result = mclInitializeApplication(NULL, 0);
if (!result){
printf("Failed to initialize MCR\n");
return result;
}
/* Initialize the MATLAB generated DLL */
result = POWERMONITORInitialize();
if(!result){
printf("Failed to initialize Library\n");
return result;
}
else{
MCRrunning=TRUE;
return result;
}
}
}
/*Function to terminate the MCR*/
void terminateMCR(void) {
MCRrunning=FALSE;
POWERMONITORTerminate();
mclTerminateApplication();
//Sometimes, repeated initialization and termination of an application may cause the application to hang. To avoid this, call mclInhibitShutdown() immediately after calling mclInitializeApplication(). For example:
//mclInhibitShutdown();
}
/*Function that wraps the top-level m function and converts C types to/from the MATLAB mxArray type*/
//int wmlfPOWERMONITOR(int* c2m_array, int size, char* message){
int wmlfPOWERMONITOR(int* c2m_array, int size, char* SerialNum, char* FilePath, char* message){
/*Define variables*/
int nargout=1;
int result=1;
/* Start MCR, load library if not done already */
int returnval=isMCRrunning();
if(!returnval){
return returnval;
}
/* Pointers to MATLAB data */
// container for the output 'output' of size 1 (is an integer)
// need to create an mxArray to use as a container for output
mxArray *msg=mxCreateString(message);
mxArray *output=mxCreateDoubleMatrix(size, size, false);
mxArray *SN=mxCreateString(SerialNum);
mxArray *FP=mxCreateString(FilePath);
/* Convert C data to MATLAB data */
// translating 'c2m_array' to 'output'
memcpy(mxGetPr(output), c2m_array, size*size*sizeof(int));
/*Call the M function*/
// result says if it passed or not
// passing in pointer 'output' by reference (&)
//result=mlfPOWERMONITOR(nargout, &output, msg);
result=mlfPOWERMONITOR(nargout, &output, SN, FP, msg);
/* Convert returned MATLAB data to C data */
// ex. memcpy(dest, src, size)
memcpy(c2m_array, mxGetPr(output), size*size*sizeof(int));
/* Clean up MATLAB variables */
mxDestroyArray(msg);
mxDestroyArray(output);
mxDestroyArray(SN);
mxDestroyArray(FP);
return result;
}
5 Comments
Raeesah Magera
on 21 Jun 2024
Hi Sergei and Jose,
We are experiencing the same issue, please can you provide some tips of how they resolved the issue.
Ra'eesah
Answers (0)
See Also
Categories
Find more on C Shared Library Integration in Help Center and File Exchange
Community Treasure Hunt
Find the treasures in MATLAB Central and discover how the community can help you!
Start Hunting!