From: Ajay on
Using MATLAB 2009b and Microsoft Visual C++ 2008 (Express Edition), I created the DLL (first_lib.dll, first_lib.h and first_lib.lib) from MATLAB function (first.m) using mcc and I would like to call it in a C code.
I am posting the complete code here with compilation erros while compiling the C code:

Reported Errors & warnings are:

1) error C2275: 'mxArray' : illegal use of this type as an expression
c:\program files\matlab\r2009a\extern\include\matrix.h(292) : see declaration of 'mxArray'

2) warning C4047: '=' : 'int' differs in levels of indirection from 'void *'

3) warning C4047: '=' : 'int' differs in levels of indirection from 'mxArray *'

4) warning C4047: 'function' : 'const mxArray *' differs in levels of indirection from 'int'

5) warning C4024: 'mxGetPr_proxy' : different types for formal and actual parameter 1

6) error C2172: 'memcpy' : actual parameter is not a pointer : parameter 2


I am posting my complete code here, where mlfFirst is the function call and are files which were created using mcc command.

#include <stdio.h>
#include <math.h>
#include "mex.h"
#include "first_lib.h"

int main()
{
float a,b,c, Ans;
a = 1; b =2; c=3;

mxArray *pmX, *pmY, *pmZ;
mxArray *pmAns = NULL;

mclInitializeApplication(NULL,0);

pmAns = mxCreateDoubleMatrix(1,1,mxREAL);
pmX = mxCreateDoubleMatrix(1,1,mxREAL);
pmY = mxCreateDoubleMatrix(1,1,mxREAL);
pmZ = mxCreateDoubleMatrix(1,1,mxREAL);

first_libInitialize();

memcpy(mxGetPr(pmX),a, sizeof(double)*1);
memcpy(mxGetPr(pmY),b, sizeof(double)*1);
memcpy(mxGetPr(pmZ),c, sizeof(double)*1);

mlfFirst(1, &pmAns, pmX, pmY, pmZ);

Ans = mxGetPr(pmAns);

first_libTerminate();

printf("%f %f\n", Ans);

mxDestroyArray(pmX);
mxDestroyArray(pmY);
mxDestroyArray(pmZ);
mxDestroyArray(pmAns);

mclTerminateApplication();

return 0;
}
From: James Tursa on
"Ajay " <ajaydashora(a)gmail.com> wrote in message <hope68$ds8$1(a)fred.mathworks.com>...
>
> float a,b,c, Ans;
:
> mxArray *pmX, *pmY, *pmZ;
> mxArray *pmAns = NULL;
:
> pmAns = mxCreateDoubleMatrix(1,1,mxREAL);
> pmX = mxCreateDoubleMatrix(1,1,mxREAL);
> pmY = mxCreateDoubleMatrix(1,1,mxREAL);
> pmZ = mxCreateDoubleMatrix(1,1,mxREAL);
:
> memcpy(mxGetPr(pmX),a, sizeof(double)*1);
> memcpy(mxGetPr(pmY),b, sizeof(double)*1);
> memcpy(mxGetPr(pmZ),c, sizeof(double)*1);

The error message means exactly what it says , the 2nd argument to memcpy needs to be a pointer. So these calls should have &a, &b, &c as arguments instead of a, b, c. Also, you have declared a, b, and c as float (32-bit single precision floating point) but are using them as double (64-bit double precision floating point). You need to declare a, b, and c as double. e.g.,

double a, b, c;

And an easier way to do this is as follows:

*mxGetPr(pmX) = a;
*mxGetPr(pmY) = b;
*mxGetPr(pmZ) = c;

>
> Ans = mxGetPr(pmAns);

Ans is a double, not a pointer to double. mxGetPr needs to be dereferenced. e.g.,

Ans = *mxGetPr(pmAns);

This all assumes that the function you are calling is expecting doubles as inputs and returns a double. Is that the case?

James Tursa
From: Ajay on
Hi James,

Many thanks......Once again I repeat that I am using the VC++ 2008 (Express) downloaded from internet as free s/w.

Following your advice, reduces the errors. However, first error is still present:

error C2275: 'mxArray' : illegal use of this type as an expression
c:\program files\matlab\r2009a\extern\include\matrix.h(292) : see declaration of 'mxArray'

Due to this error, C compiler is not recognizing either of pmX, pmY, PmZ.

I added the pragmas to my code to avoid any library to be missing in compiler settings and I changed my code as:

#ifdef _MSC_VER // if MS Visual C++
#pragma warning(push)
#pragma warning(disable:4996)
#pragma comment(lib, "libdfblas.lib")
#pragma comment(lib, "libdflapack.lib")
#pragma comment(lib, "libemlrt.lib")
#pragma comment(lib, "libeng.lib")
#pragma comment(lib, "libfixedpoint.lib")
#pragma comment(lib, "libmat.lib")
#pragma comment(lib, "libmex.lib")
#pragma comment(lib, "libmwblas.lib")
#pragma comment(lib, "libmwlapack.lib")
#pragma comment(lib, "libmwmathutil.lib")
#pragma comment(lib, "libmwservices.lib")
#pragma comment(lib, "libmx.lib")
#pragma comment(lib, "libut.lib")
#pragma comment(lib, "mclcom.lib")
#pragma comment(lib, "mclcommain.lib")
#pragma comment(lib, "mclmcr.lib")
#pragma comment(lib, "mclmcrrt.lib")
#pragma comment(lib, "mclxlmain.lib")
#pragma comment(lib, "first_lib.lib")
#endif

#include <stdio.h>
#include <math.h>
#include "mex.h"
#include "first_lib.h"

int main()
{
double a,b,c, Ans;
a = 1; b =2; c=3;

mxArray *pmX, *pmY, *pmZ;
mxArray *pmAns = NULL;

mclinitializeApplication(NULL,0);

*mxGetPr(pmX) = a;
*mxGetPr(pmY) = b;
*mxGetPr(pmZ) = c;

first_libInitialize();

memcpy(mxGetPr(pmX),&a, sizeof(double)*1);
memcpy(mxGetPr(pmY),&b, sizeof(double)*1);
memcpy(mxGetPr(pmZ),&c, sizeof(double)*1);

mlfFirst(1,&pmAns,pmX,pmY,pmZ);

Ans = *mxGetPr(pmAns);

first_libTerminate();

printf("%f %f\n", Ans);

mxDestroyArray(pmX);
mxDestroyArray(pmY);
mxDestroyArray(pmZ);
mxDestroyArray(pmAns);

mclTerminateApplication();

return 0;
}




"James Tursa" <aclassyguy_with_a_k_not_a_c(a)hotmail.com> wrote in message <hopgdk$grd$1(a)fred.mathworks.com>...
> "Ajay " <ajaydashora(a)gmail.com> wrote in message <hope68$ds8$1(a)fred.mathworks.com>...
> >
> > float a,b,c, Ans;
> :
> > mxArray *pmX, *pmY, *pmZ;
> > mxArray *pmAns = NULL;
> :
> > pmAns = mxCreateDoubleMatrix(1,1,mxREAL);
> > pmX = mxCreateDoubleMatrix(1,1,mxREAL);
> > pmY = mxCreateDoubleMatrix(1,1,mxREAL);
> > pmZ = mxCreateDoubleMatrix(1,1,mxREAL);
> :
> > memcpy(mxGetPr(pmX),a, sizeof(double)*1);
> > memcpy(mxGetPr(pmY),b, sizeof(double)*1);
> > memcpy(mxGetPr(pmZ),c, sizeof(double)*1);
>
> The error message means exactly what it says , the 2nd argument to memcpy needs to be a pointer. So these calls should have &a, &b, &c as arguments instead of a, b, c. Also, you have declared a, b, and c as float (32-bit single precision floating point) but are using them as double (64-bit double precision floating point). You need to declare a, b, and c as double. e.g.,
>
> double a, b, c;
>
> And an easier way to do this is as follows:
>
> *mxGetPr(pmX) = a;
> *mxGetPr(pmY) = b;
> *mxGetPr(pmZ) = c;
>
> >
> > Ans = mxGetPr(pmAns);
>
> Ans is a double, not a pointer to double. mxGetPr needs to be dereferenced. e.g.,
>
> Ans = *mxGetPr(pmAns);
>
> This all assumes that the function you are calling is expecting doubles as inputs and returns a double. Is that the case?
>
> James Tursa
From: AJ on
"Ajay " <ajaydashora(a)gmail.com> wrote in message <hopjmk$4c0$1(a)fred.mathworks.com>...
> Hi James,
>
> Many thanks......Once again I repeat that I am using the VC++ 2008 (Express) downloaded from internet as free s/w.
>
> Following your advice, reduces the errors. However, first error is still present:
>
> error C2275: 'mxArray' : illegal use of this type as an expression
> c:\program files\matlab\r2009a\extern\include\matrix.h(292) : see declaration of 'mxArray'

I think see the problem - in "C" all the variable declarations need to be at the top of a code segment. Move the assignment of a, b, and c to below the mxArray* declaritors.

[snip]

> double a,b,c, Ans;
//a = 1; b =2; c=3;
>
> mxArray *pmX, *pmY, *pmZ;
> mxArray *pmAns = NULL;
a = 1; b =2; c=3;
>
> mclinitializeApplication(NULL,0);
>

You will still need these lines:
pmX = mxCreateDoubleMatrix(1,1,mxREAL);
pmY = mxCreateDoubleMatrix(1,1,mxREAL);
pmZ = mxCreateDoubleMatrix(1,1,mxREAL);

> *mxGetPr(pmX) = a;
> *mxGetPr(pmY) = b;
> *mxGetPr(pmZ) = c;
>

HTH,
AJ
From: Ajay on
Hi,

Many thanks.....it is working now !!!




"AJ" <aj(a)johnson.lmco.com> wrote in message <hoq9es$fml$1(a)fred.mathworks.com>...
> "Ajay " <ajaydashora(a)gmail.com> wrote in message <hopjmk$4c0$1(a)fred.mathworks.com>...
> > Hi James,
> >
> > Many thanks......Once again I repeat that I am using the VC++ 2008 (Express) downloaded from internet as free s/w.
> >
> > Following your advice, reduces the errors. However, first error is still present:
> >
> > error C2275: 'mxArray' : illegal use of this type as an expression
> > c:\program files\matlab\r2009a\extern\include\matrix.h(292) : see declaration of 'mxArray'
>
> I think see the problem - in "C" all the variable declarations need to be at the top of a code segment. Move the assignment of a, b, and c to below the mxArray* declaritors.
>
> [snip]
>
> > double a,b,c, Ans;
> //a = 1; b =2; c=3;
> >
> > mxArray *pmX, *pmY, *pmZ;
> > mxArray *pmAns = NULL;
> a = 1; b =2; c=3;
> >
> > mclinitializeApplication(NULL,0);
> >
>
> You will still need these lines:
> pmX = mxCreateDoubleMatrix(1,1,mxREAL);
> pmY = mxCreateDoubleMatrix(1,1,mxREAL);
> pmZ = mxCreateDoubleMatrix(1,1,mxREAL);
>
> > *mxGetPr(pmX) = a;
> > *mxGetPr(pmY) = b;
> > *mxGetPr(pmZ) = c;
> >
>
> HTH,
> AJ