问题
I want to create a C++ Shared library from Matlab using deloytool and use it in MVS. I compile a function name 'foo.m', as the result I got list of files (.h,.cpp,.lib,...) and I found the function in 'fooCpplib.h' is as follow:
extern LIB_fooCpplib_CPP_API void MW_CALL_CONV foo(int nargout, mwArray& y, const mwArray& x);
Then I create a MVS project (2010), window form application, with 2 textbox and 2 click button, one textbox named inBox, and another named outBox. The code inside button_click is as follow:
private: System::Void button1_Click(System::Object^ sender, System::EventArgs^ e) {
double input = System::Double::Parse(inBox->Text);
mxArray *x_ptr;
mxArray *y_ptr=NULL;
double *y;
// Create an mxArray to input into mlfFoo
x_ptr = mxCreateDoubleScalar(input);
// Call the implementation function
// Note the second input argument should be &y_ptr instead of y_ptr.
foo(1,&y_ptr,x_ptr);
// The return value from mlfFoo is an mxArray.
// Use mxGetpr to get a pointer to data it contains.
y = (double*)mxGetPr(y_ptr);
// display the result in the form
outBox->Text = ""+*y;
//clean up memory
mxDestroyArray(x_ptr);
mxDestroyArray(y_ptr);
}
When I build the project, the error was occurred as below:
error C2664: 'foo' : cannot convert parameter 2 from 'mxArray **' to 'mwArray &'
Types pointed to are unrelated; conversion requires reinterpret_cast, C-style cast or function-style
cast.
Note: I already included 'fooCpplib.h' in the .cpp source file.
Could anyone help me about this! Thank you!
回答1:
When a parameter is declared as
TypeName &argName
it means that argName
is a reference. In C++ you can pass parameters by reference, which allows the function modify the variable that you pass to it (among other things).
If you have a pointer, but a function expects a reference, you need to dereference the pointer in the call with an asterisk, rather than taking the address of a pointer with an ampersand:
foo(1,*y_ptr,*x_ptr);
// ^ ^
// | |
// Here and here
You can think of variables, pointers, pointers to pointers, etc. in terms of level of indirection. Variables have a level of indirection of zero; pointers have level of indirection of one; pointers to pointers have level of indirection of two, and so on.
Adding an ampersand increases the level of indirection; adding an asterisk decreases it. Like variables, references have level of indirection of zero. If you have a pointer and you need a variable, you must decrease the level of indirection by prepending an asterisk.
Another problem in your code is that foo
expects references to mwArray
, with a "w", but you are passing references to mxArray
, with an "x". The types need to match, otherwise the compiler is not going to take your program.
回答2:
mwArray&
is a reference type. It's a "reference to mwArray
". However, you're trying to pass &y_ptr
which gives you a mwArray**
, or a "pointer to pointer to mwArray
". Instead, you should be dereferencing y_ptr
to get a mwArray
which you can pass by reference. The same is true for the third argument.
foo(1,*y_ptr,*x_ptr);
However, you have another problem, which is that y_ptr
is null. You need it to be pointing at a mwArray
object to dereference it.
来源:https://stackoverflow.com/questions/16374140/cannot-convert-parameter-2-from-mxarray-to-mwarray