Passing a pointer from Matlab to C

9 ビュー (過去 30 日間)
Emil A Atz
Emil A Atz 2017 年 3 月 28 日
編集済み: Guillaume 2017 年 3 月 30 日
I am attempting to pass a matrix from a class in Matlab to a code in C. The code in C cannot be changed and requires a double* to be passed in as an argument. I am trying to use libpointer(...) to modify the matrix into something that can be passed to the C code through a calllib(...) function.
I cannot post all of the code because it is quite extensive. The function of the Matlab code reads:
function obj = set.RP(obj, vals)
rho = vals{1};
pres = vals{2};
if strcmp(rho,'None')
rho = obj.R;
end
if strcmp(pres, 'None')
pres = obj.P;
end
disp(rho)
disp(pres)
idxptr = libpointer('doublePtr',[rho, pres]);
disp(idxptr)
calllib('canteraLib', 'thermo_set_RP', obj.thermo, idxptr)
end
The function in the C code reads:
int thermo_set_RP(int n, double* vals)
{
try{
ThermoCabinet::item(n).setState_RP(vals[0], vals[1]);
return 0;
} catch (...) {
return handleAllExceptions(-1, ERR);
}
}
Thank you for your time
-Emil
  5 件のコメント
Guillaume
Guillaume 2017 年 3 月 28 日
編集済み: Guillaume 2017 年 3 月 28 日
I doubt it matters, but the sample C code is not C, but C++. C does not have try catch or namespaces.
Is the C++ function defined as extern "C" in its header file?
"the code fails". And that means ...? access violation? BSOD? wrong value returned? an error is thrown by matlab?
Emil A Atz
Emil A Atz 2017 年 3 月 30 日
Guillaume,
Yes, the C++ file has Extern "C" in the headerfile. And when I say the code fails, the return handleAllExceptions(-1, ERR); returns -1. Not sure what the error really is in the C code because it doesn't show it in MatLab.
The C code requires a pointer to an array. I cannot seem to successfully pass an array to the C code with the libpointer. What are your recommendations for passing an array as a pointer?
Thanks for the response.
-Emil

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

採用された回答

Guillaume
Guillaume 2017 年 3 月 30 日
Once again, it's C++ code, not C code. The code you've shown would not compile through a C compiler.
You don't need to use libpointer to pass a pointer to double to the dll. If you've given the correct header file to loadlibrary, matlab already knows to pass a pointer. There is nothing special you need to do:
assert(strcmp(class([rho, pres]), 'double')));
calllib('canteraLib', 'thermo_set_RP', obj.thermo, [rho, pres])
is all that is needed (assuming both rho and pres are double)
How do you infer that the pointer is not passed correctly if all you know is that handleAllExceptions gets triggered? If the dll had received an invalid pointer, it is more likely that you'd get an access violation error which would terminate matlab (i.e. you'd get a crash). The try ... catch statement would not detect invalid pointers, therefore it's much more likely that the values you're passing are not correct.
The best way for you to find what is going on is to attach a debugger to matlab, set a breakpoint to that function in the dll and step through the code as it is executed. Then see what happens with
ThermoCabinet::item(n).setState_RP
which is the line causing the error
  2 件のコメント
Emil A Atz
Emil A Atz 2017 年 3 月 30 日
You're right, it is C++ code. And we currently have something, (what we call the "old MatLab interface" with the software) that functions just fine using the ThermoCabinet::item(n).setState_RP. This is because we use mxGetPR in accompanying C++ code. We use the header #include "mex.h" which we are attempting to avoid so we can have an interface that does not require the mex compiler.
rho and pres are doubles in the MATLAB function, and in order to be properly passed into the C++ code they need to be in the double* format but they do not seem to be passed properly because the code outputs the -1.
Running the code with the "old interface" functions just fine but uses MEX functions. We do not want to use these MEX functions.
Guillaume
Guillaume 2017 年 3 月 30 日
編集済み: Guillaume 2017 年 3 月 30 日
I've just build the most basic dll I could using your code snippet:
Answers.hpp:
#ifdef __cplusplus
extern "C" {
#endif
__declspec(dllexport) int thermo_set_RP(int, double*);
#ifdef __cplusplus
}
#endif
Answers.cpp:
#include "stdafx.h"
#include "Answers.h"
#define ERR 0
class err {};
namespace ThermoCabinet {
class Item {
public:
void setState_RP(double v1, double v2) {
if (v1 != 10 || v2 != 20) throw err();
}
};
class Items {
Item it;
public:
Item operator()(int n) {
if (n != 5) throw err();
return it;
}
};
Items item;
}
int handleAllExceptions(int value, int error) {return -1;}
//your code snippet
int thermo_set_RP(int n, double* vals)
{
try {
ThermoCabinet::item(n).setState_RP(vals[0], vals[1]);
return 0;
}
catch (...) {
return handleAllExceptions(-1, ERR);
}
}
Te above will throw unless n is 5 and the double array is [10 20]. Calling that from matlab works without issues and no need for libpointer:
>>loadlibrary('Answers.dll', 'Answers.hpp');
>>calllib('Answers', 'thermo_set_RP', 5, [10 20]) %correct values
ans =
0
>>callib('Answers', 'thermo_set_RP', 5, [10 15]) %wrong values
ans =
-1
As I said, the error you get has nothing to do with passing the double pointer. Matlab passes it just fine. It's something else to do with your code. The only way to find out is to attach a debugger to the dll and see what triggers the catch.

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

その他の回答 (0 件)

カテゴリ

Help Center および File ExchangeMATLAB Compiler SDK についてさらに検索

タグ

Community Treasure Hunt

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

Start Hunting!

Translated by