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

2 ビュー (過去 30 日間)
shome
shome 2015 年 11 月 18 日
コメント済み: Titus Edelhofer 2015 年 11 月 18 日
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;
}

採用された回答

James Tursa
James Tursa 2015 年 11 月 18 日
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.

その他の回答 (1 件)

Titus Edelhofer
Titus Edelhofer 2015 年 11 月 18 日
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 件のコメント
James Tursa
James Tursa 2015 年 11 月 18 日
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 2015 年 11 月 18 日
James, you are of course right...

サインインしてコメントする。

カテゴリ

Help Center および File ExchangeJava Package Integration についてさらに検索

Community Treasure Hunt

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

Start Hunting!

Translated by