I have a C function created using Compiler CDK and it's returning a large array but it's MxArray** type. How do I access all the data retunred to the calling C function?

Here's the C calling function from main().
#include <stdio.h>
#include "libMPrime_CA_P.h"
#include "matrix.h"
int main(void)
{
libMPrime_CA_PInitialize();
mxArray *mydata;
int numargs=1;
int rtn;
rtn = mlfMPrime_CA_P(numargs,&mydata); // Function that was created using Compiler CDK returns MxArray**
printf("Function Completed rtn:%0d with numargs =%d\n",rtn,numargs);
libMPrime_CA_PTerminate();
return 0;
}
//Here's the funcrion header in the library.
extern LIB_libMPrime_CA_P_C_API bool MW_CALL_CONV mlfMPrime_CA_P(int nargout, mxArray** a);
Here's the function header written in MATLAB
function [a] = MPrime_CA_P
a is 1 x 127689 double values
....
What does nargout do and how do I access all the data in MxArray** a?

Answers (1)

A function signature like that typically means that the mlfMPrime_CA_P( ) function is creating an mxArray and then returning the address of that mxArray in the variable mydata. That is, mydata is intended to be an output of the function call. So you can use mydata like an ordinary mxArray pointer and use normal API function on it in the calling function. E.g., something like:
mxArray *mydata = NULL; // You should initialize it in case the function doesn't set it
:
rtn = mlfMPrime_CA_P(numargs,&mydata);
if( mydata != NULL ) {
printf("Function returned an mxArray of class %s\n",mxGetClassName(mydata));
// Other API functions to manipulate mydata go here
mxDestroyArray(mydata);
}

17 Comments

I get the following when using mxGetClassName.
/bin/ld: /tmp/cc4TPMnY.o: undefined reference to symbol 'mxGetClassNameDeployed'
/opt/tools/matlab_r2019b/runtime/glnxa64/libmwmclmcrrt.so.9.7: error adding symbols: DSO missing from command line
collect2: error: ld returned 1 exit status
I don't deploy code so am unfamiliar with that process. Maybe not all the API functions are supported. What if you tried something simple like mxIsDouble(mydata) instead:
printf("Function returned an mxArray, mxIsDouble = %d\n",mxIsDouble(mydata));
Do you know what type of mxArray the function is supposed to create?
In the matlab code the output is a 1 row X 127683 colums.
What I have read is that the mxArray is a special MATLAB data type that can't be accessed in a C calling function.
I tired using the mex functions you are referring to but have not been able to use them, although I had #include "mex.h", but doing that had issue too.
/bin/ld: /tmp/ccChtbcl.o: undefined reference to symbol 'mxIsDouble_800_proxy'
I must be missing another library.
So, you need to link with the MATLAB API object library code in order to use any of those API functions. If you can't do that, then you will be forced to hack into the mxArray in order to get at the data, but that would be a very last resort. Linking with the API library is what you should be doing, as long as the mlfMPrime_CA_P function is using the same mxArray definition.
The mex.h header is not what you need (that is used when you are going to build a mex routine with mexFunction interface).
Can you tell me where the MATLAB API object library code is?
Look for a libmx library file. E.g., in the matlabroot/extern/lib/etc directories ... whatever is appropriate for your system.
Can't find that library. The linux install has the following, in extern/lib
c_exportsmexfileversion.map fexport.map fortran_exportsmexfileversion.map mexFunction.map
James, thank you for looking into this.
There is no libmx file (with appropriate library extension) anywhere under matlabroot? What version of MATLAB are you running?
I did find it under the bin directory. Here's my compile line and error. dataval replaced mydata
gcc -I/opt/tools/matlab_r2019b/extern/include -L. libMPrime_CA_P.so -L/opt/tools/matlab_r2019b/bin/glnxa64/libmx.so test_matlab.c
test_matlab.c:26:6: warning: passing argument 1 of \u2018mxGetNumberOfDimensions_800_proxy\u2019 from incompatible pointer type [enabled by default]
printf("Function returned an mxArray of class %s\n",mxGetNumberOfDimensions(&dataval));
/bin/ld: /tmp/ccgjnqJE.o: undefined reference to symbol 'mxGetNumberOfDimensions_800_proxy'
/opt/tools/matlab_r2019b/runtime/glnxa64/libmwmclmcrrt.so.9.7: error adding symbols: DSO missing from command line
collect2: error: ld returned 1 exit status
You need to change the %s format, which is for a string, to an integer format like %d.
Same error after changing the %s to %d.
mxGetNumberOfDimensions_800_proxy <-- This seems the cause of the current error. I'll try calling support to see if they can help and if they fix it post the result.
What is the definition of dataval? Why aren't you calling it as mxGetNumberOfDimensions(dataval)?
It's a pointer to the mxArray.
Here's the function call in main() : rtn = mlfMPrime_CA_P(numargs,&dataval);
Here's the prototype created using compiler.
extern LIB_libMPrime_CA_P_C_API bool MW_CALL_CONV mlfMPrime_CA_P(int nargout, mxArray** dataval);
That didn't answer my question. Please post the exact code that defines dataval, not a sentence with your interpretation of what it is.
The matlab function that is converted using compiler SDK is shown below.
%%%%%%%%%%%%%%%%
function [dataval] = MPrime_CA_P
dataval = 2;
end
%%%%%%%%%%%%%%%%%
I created a simple debug version of the original function. This simple version creates the same extern function mlfMPrime_CA_P as shown in my last comment. The extern function shows dataval as a MxArray **.
I'm still not making myself clear. Here is what I would expect the C-code to look like:
mxArray *dataval = NULL;
:
rtn = mlfMPrime_CA_P(numargs,&dataval);
if( dataval ) {
printf("Function returned an mxArray, ndim = %d\n",mxGetNumberOfDimensions(dataval));
}
Do your data types and calling sequence look like the above?
I had:
printf("Function returned an mxArray, ndim = %d\n",mxGetNumberOfDimensions(&dataval));
Changed to:
printf("Function returned an mxArray, ndim = %d\n",mxGetNumberOfDimensions(dataval));
Now error is:
/bin/ld: /tmp/ccKZSl27.o: undefined reference to symbol 'mxGetNumberOfDimensions_800_proxy'
/opt/tools/matlab_r2019b/runtime/glnxa64/libmwmclmcrrt.so.9.7: error adding symbols: DSO missing from command line
collect2: error: ld returned 1 exit status

Sign in to comment.

Categories

Asked:

on 22 May 2020

Commented:

on 28 May 2020

Community Treasure Hunt

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

Start Hunting!