【发布时间】:2015-03-12 14:48:55
【问题描述】:
我正在连接 Matlab 和 C 代码,以便能够直接使用 Matlab 中的一些 C 函数。我知道这些函数的原型,但里面的代码可能会改变。 为了接口这一切,我在 Matlab 中使用 loadlibrary 和 calllib,我不想使用 MEXFiles。
在 C 代码中,定义了一些结构。尽管如此,定义代码基本组件的那个可能会改变:它包含一些结构和变量,但是可以在这个中添加一些其他结构,我希望 Matlab 能够处理所有这些。
但是,正如 Mathworks 所说:
不支持嵌套结构或包含指向结构的指针的结构。但是,MATLAB 可以访问在外部库中创建的结构数组。
所以我不能在 Matlab 中直接存储嵌套结构。例如,主要成分是结构(a)。这个包含另一个结构(b)。并且 (b) 包含指向函数的指针。 如果我使用 libstruct 直接将 (a) 存储在变量中,当我在参数中调用带有 (a) 的 C 方法时,我们可以看到指针丢失了。最糟糕的是,C 代码知道指向结构 (b) 的指针是什么,但他无法访问指向的函数。 尽管如此,通过之前在 Matlab 中创建这个结构 (b),它可以工作,但它是特定于 (b) 的,我不能对其他嵌套结构做同样的事情。
这就是为什么我认为我必须阻止 Matlab 查找变量的类型。我只需要给它一个指向结构的指针并锁定所有与这个指针相关的东西,以便能够在带有 calllib 的 C 函数的参数中传递这个指针。
这就是我的问题:你知道我是否可以锁定包含结构 (a) 和所有相关内容的内存的一部分吗?你认为我可以阻止 Matlab 看这个指针是什么吗?
事实上,我只是想在一个 C 函数中创建一个嵌套结构并在另一个 C 函数中重新使用它,但是用 Matlab 调用这两个 C 函数(不使用 MexFiles)。
谢谢! :)
C 代码
结构(一)
typedef struct {
fmi2Real *r;
fmi2Integer *i;
fmi2Boolean *b;
fmi2String *s;
fmi2Boolean *isPositive;
fmi2Real time;
fmi2String instanceName;
fmi2Type type;
fmi2String GUID;
const fmi2CallbackFunctions *functions;
fmi2Boolean loggingOn;
fmi2Boolean logCategories[NUMBER_OF_CATEGORIES];
fmi2ComponentEnvironment componentEnvironment;
ModelState state;
fmi2EventInfo eventInfo;
int isDirtyValues; // !0 is true
} ModelInstance;
可以在这个结构(a)中添加其他结构。
结构(b)
typedef struct {
const fmi2CallbackLogger logger;
const fmi2CallbackAllocateMemory allocateMemory;
const fmi2CallbackFreeMemory freeMemory;
const fmi2StepFinished stepFinished;
const fmi2ComponentEnvironment componentEnvironment;
} fmi2CallbackFunctions;
typedef void (*fmi2CallbackLogger) (fmi2ComponentEnvironment, fmi2String, fmi2Status, fmi2String, fmi2String, ...);
typedef void* (*fmi2CallbackAllocateMemory)(size_t, size_t);
typedef void (*fmi2CallbackFreeMemory) (void*);
typedef void (*fmi2StepFinished) (fmi2ComponentEnvironment, fmi2Status);
其中一个 C 函数的原型(第一个创建主要组件的函数)
fmi2Component fmi2Instantiate(fmi2String instanceName, fmi2Type fmuType, fmi2String fmuGUID,
fmi2String fmuResourceLocation, const fmi2CallbackFunctions *functions,
fmi2Boolean visible, fmi2Boolean loggingOn);
typedef void* fmi2Component;
Matlab 代码
调用函数 fmi2Instantiate 并创建组件。
fmu.component=calllib(model, 'fmi2Instantiate', libpointer('int8Ptr', fmu.instanceName), fmu.type, libpointer('int8Ptr', fmu.guid), libpointer('int8Ptr', resourceLocation), fmu.callbackFunctions, visible, loggingOn);
该组件将进一步传入参数给其他 C 函数。
【问题讨论】:
-
1)
struct a、struct b和 c 函数的一些模拟代码以及您希望如何从 matlab 中调用它们会有所帮助。 2) 为什么要绝对避免让 mex 文件为您制作胶水并“按原样”处理 c-lib? -
1) 我添加了您要求的内容- :) 2) 我想避免使用 MexFiles,因为我加载的 DLL 具有我知道的特定原型的函数,但里面的内容可能会改变,并且我不想为每个 DLL 重新构建一些 MexFiles,而只是加载一个 DLL 就可以了! :)
-
2) 现在更有意义 .. 即使作为替代或备份解决方案,您可以将 dll 名称作为参数传递给 mex 函数,并让它为您加载
mexCallMATLAB...嗯...让我们阅读以获取更多详细信息;)
标签: matlab pointers structure loadlibrary