matlab engine giving wrong result when called in a function in Cpp file
2 Ansichten (letzte 30 Tage)
Ältere Kommentare anzeigen
shome
am 18 Nov. 2015
Kommentiert: Titus Edelhofer
am 18 Nov. 2015
matlab engine call inside function: i try to sort an array of numbers & write the result to a file(using dlmwrite). also i display them on the screen. * when i sort { 0, 5, 2, 7, 3, 9, 1, 6, 8, 4 } i get an array of ten zeros(both at std::cout & using dlmwrite)*
my code for the function:
int call_matlab_processing(double double_array[], int size_double_array)
{
// its just a sorting algo, sorting being implemented by matlab
double * sorted;
Engine *ep;
mxArray *T = NULL, *result = NULL;
if (!(ep = engOpen(""))) {
fprintf(stderr, "\nCan't start MATLAB engine\n");
return 1;
}
T = mxCreateDoubleMatrix(1,size_double_array, mxREAL);
memcpy((void *)mxGetPr(T), (void *)double_array, sizeof(double_array));
engPutVariable(ep, "T", T);
engEvalString(ep, "[D] = sort(T,'descend')");
engEvalString(ep, "dlmwrite('myFile.txt',D)"); * * *// writes 0 0 0 ... 0 to file***
result = engGetVariable(ep,"D");
sorted=(double *)mxGetData(result);
* *// i try to print the contents of the sorted array, but it gives 0 0 0 ...0**
for(int i = 0; i < size_double_array;i++)
{
std::cout<< "double_array at "<< i<< "="<< *sorted<< std::endl;
sorted++;
}
mxDestroyArray(T);
mxDestroyArray(result);
engEvalString(ep, "close;");
engClose(ep);
return 0;
}
0 Kommentare
Akzeptierte Antwort
James Tursa
am 18 Nov. 2015
These lines:
int call_matlab_processing(double double_array[], int size_double_array,double * sorted, double * indices_cpp)
{
:
memcpy((void *)mxGetPr(T), (void *)double_array, sizeof(double_array));
The first argument of the function call_matlab_processing is the variable double_array. It turns out that this variable is of type "pointer to double" (i.e., double * ). I know it looks like you have declared it as an array, but that syntax is misleading. When used in a function argument, the notation
double variable_name[]
is equivalent to the notation
double *variable_name
In fact, even if you had use an explicit size it would have made no difference to the compiler. I.e., this notation in a function argument
double variable_name[10]
is also equivalent to the notation
double *variable_name
That is, the compiler sees that argument as a pointer, not as an array (you can't pass whole arrays in C/C++ function arguments this way). So downstream in your code when you use sizeof(double_array), it is equivalent to doing sizeof(double * ). The result will be either 4 (on 32-bit) or 8 (on 64-bit). So you are definitely not copying all of the elements in that memcpy call. You need to do this instead:
memcpy((void *)mxGetPr(T), (void *)double_array, size_double_array*sizeof(double));
Also, FYI you don't really need the (void *) casts since converting pointers to/from void * is something the C/C++ compiler will automatically do for you.
0 Kommentare
Weitere Antworten (1)
Titus Edelhofer
am 18 Nov. 2015
Hi,
first of all, your memcpy copies just 4 or 8 bytes but not the array:
memcpy((void *)mxGetPr(T), (void *)double_array, sizeof(double_array));
You need to replace by
memcpy((void *)mxGetPr(T), (void *)double_array, size_double_array * sizeof(double));
And for the result you would need to do:
double *sorted;
sorted = mxGetPr(result);
for (int i=0; i<size_double_array; i++) {
std::cout << sorted[i] << endl;
}
Titus
2 Kommentare
James Tursa
am 18 Nov. 2015
He is printing out *sorted and doing sorted++ inside the loop, so he should get the same result as sorted[i].
Siehe auch
Kategorien
Mehr zu Java Package Integration finden Sie in Help Center und File Exchange
Community Treasure Hunt
Find the treasures in MATLAB Central and discover how the community can help you!
Start Hunting!