matlab engine giving wrong result when called in a function in Cpp file

2 vues (au cours des 30 derniers jours)
shome
shome le 18 Nov 2015
Commenté : Titus Edelhofer le 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;
}

Réponse acceptée

James Tursa
James Tursa le 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.

Plus de réponses (1)

Titus Edelhofer
Titus Edelhofer le 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 commentaires
James Tursa
James Tursa le 18 Nov 2015
He is printing out *sorted and doing sorted++ inside the loop, so he should get the same result as sorted[i].
Titus Edelhofer
Titus Edelhofer le 18 Nov 2015
James, you are of course right...

Connectez-vous pour commenter.

Catégories

En savoir plus sur Java Package Integration dans Help Center et File Exchange

Community Treasure Hunt

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

Start Hunting!

Translated by