此问题的来源是How to use "global static" variable in matlab function called in c。
我正在尝试将“全局变量”封装到对象中。但是我不知道如何使用MATLAB Compiler (mcc)
将matlab类导出到c ++为此,我尝试了标准命令
mcc -W cpplib:Vowel4 -T link:lib Vowel4.m
classdef Vowel4
properties
x
y
end
methods
Vowel4
A
B
end
end
生成的lib实际上是独立的函数,而不是c ++类。
如何将Matlab中的类编译成c ++类?
我一直在寻找答案,但没有找到答案。
显然matlab命令不适合这种情况。但是我找不到有关将matlab类构建到c ++类中的任何信息。
==========================编辑==================== ====
实际的cpp代码如下:@Alan
mclInitializeApplication(NULL, 0);
loadDataInitialize();
soundByCoefInitialize();
loadData();
mwArray F(4, 1, mxDOUBLE_CLASS);
float test[4];
for ( ;; ){
const Frame frame = controller.frame();
const FingerList fingers = frame.fingers();
if ( !fingers.empty() ){
for ( int i = 0; i < 4; i ++ ){
double v = fingers.count() > i ? (fingers[i].tipPosition().y / 50) - 2 : 0;
F(i+1,1) = v;
test[i] = v;
cout << v << ' ';
}
cout << endl;
soundByCoef(F);
}
}
这里matlabA()对应于loadData(),它加载数据,soundByCoef(F)对应matlabB(),它在主循环中完成工作。
答案 0 :(得分:6)
如Alan所述,I was仅建议使用句柄类作为全局变量的容器(这样的对象将通过引用传递)。创建的对象不打算由C ++代码直接操作(它将存储在通用的mxArray/mwArray
C / C ++结构中)。
As far作为I know,在使用MATLAB编译器构建共享库时,不能直接将classdef样式的MATLAB类编译成适当的C ++类。它只支持构建常规功能。您可以为MATLAB类成员方法创建功能接口,但这是一个不同的故事......
也许一个完整的例子可以帮助说明我的想法。首先让我们在MATLAB端定义代码:
这是用于存储全局变量的句柄类。
classdef GlobalData < handle
%GLOBALDATA Handle class to encapsulate all global state data.
%
% Note that we are not taking advantage of any object-oriented programming
% concept in this code. This class acts only as a container for publicly
% accessible properties for the otherwise global variables.
%
% To manipulate these globals from C++, you should create the class API
% as normal MATLAB functions to be compiled and exposed as regular C
% functions by the shared library.
% For example: create(), get(), set(), ...
%
% The reason we use a handle-class instead of regular variables/structs
% is that handle-class objects get passed by reference.
%
properties
val
end
end
一个包装函数,用作上述类
的构造函数function globals = create_globals()
%CREATE_GLOBALS Instantiate and return global state
globals = GlobalData();
globals.val = 2;
end
MATLAB函数将作为C ++函数公开
function out = fcn_add(globals, in)
% receives array, and return "input+val" (where val is global)
out = in + globals.val;
end
function out = fcn_times(globals, in)
% receives array, and return "input*val" (where val is global)
out = in .* globals.val;
end
将上述文件存储在当前目录中,让我们使用MATLAB编译器构建C ++共享库:
>> mkdir out
>> mcc -W cpplib:libfoo -T link:lib -N -v -d ./out create_globals.m fcn_add.m fcn_times.m
您应该期望以下生成的文件(我在Windows计算机上):
./out/libfoo.h
./out/libfoo.dll
./out/libfoo.lib
接下来,我们可以创建一个示例C ++程序来测试库:
// Sample program that calls a C++ shared library created using
// the MATLAB Compiler.
#include <iostream>
using namespace std;
// include library header generated by MATLAB Compiler
#include "libfoo.h"
int run_main(int argc, char **argv)
{
// initialize MCR
if (!mclInitializeApplication(NULL,0)) {
cerr << "Failed to init MCR" << endl;
return -1;
}
// initialize our library
if( !libfooInitialize() ) {
cerr << "Failed to init library" << endl;
return -1;
}
try {
// create global variables
mwArray globals;
create_globals(1, globals);
// create input array
double data[] = {1,2,3,4,5,6,7,8,9};
mwArray in(3, 3, mxDOUBLE_CLASS, mxREAL);
in.SetData(data, 9);
// create output array, and call library functions
mwArray out;
fcn_add(1, out, globals, in);
cout << "Added matrix:\n" << out << endl;
fcn_times(1, out, globals, in);
cout << "Multiplied matrix:\n" << out << endl;
} catch (const mwException& e) {
cerr << e.what() << endl;
return -1;
} catch (...) {
cerr << "Unexpected error thrown" << endl;
return -1;
}
// destruct our library
libfooTerminate();
// shutdown MCR
mclTerminateApplication();
return 0;
}
int main()
{
mclmcrInitialize();
return mclRunMain((mclMainFcnType)run_main, 0, NULL);
}
让我们构建独立程序:
>> mbuild -I./out main.cpp ./out/libfoo.lib -outdir ./out
最后运行可执行文件:
>> cd out
>> !main
Added matrix:
3 6 9
4 7 10
5 8 11
Multiplied matrix:
2 8 14
4 10 16
6 12 18
HTH
答案 1 :(得分:2)
继previous post中的线程之后,建议不是将函数包装在一个类中,而是使用一个类来传递编译使你无法使用的全局变量。 / p>
classdef Foo < handle
properties
value
end
methods
function obj = Foo(value)
obj.value = value;
end
end
end
注意:类Foo扩展handle
类以使其通过引用传递,而不是按值传递。请参阅:the comparison between handle and value classes。
function foo = matlabA()
foo = new Foo(1);
end
function matlabB(foo)
foo.value
end
据我所知,matlab编译器不会编译代码,而是编译packages it with a copy of the MATLAB Component Runtime并编写一些包装器函数来处理从c / c ++代码调用所述运行时。
我建议避免在matlab和c / c ++之间来回跳转太多;转换数据类型和调用MCR肯定会有一些开销。所有我真正用它来包装一个复杂但独立的matlab脚本(即:不需要通过所述脚本中途与c / c ++代码交互)作为一个函数,或者打包代码以便部署到环境中没有完整的matlab副本。
作为一个有趣的旁注:如果你在Matlab中调用C ++ ,并且C ++代码需要访问全局变量,事情会容易得多。您可以通过将C ++代码包装到mexFunction并编译它来完成此操作。在您需要访问Matlab工作区中的变量的位置,您可以使用mexGetVariablePtr来执行此操作,该{{3}}将返回指向数据的只读指针。您正在访问的变量可以位于全局工作空间中,也可以位于调用mexFunction的函数中。
通过这种方法,我建议自由地评论你在C ++和Matlab代码中得到的变量,因为它们之间的链接在Matlab方面可能并不明显;你不希望别人以后来,编辑脚本并想知道它为什么会破碎。
在这种情况下,似乎C ++方面并不真正需要访问数据,因此您可以重构它以让matlab通过包装“获取当前位置的手指”来执行调用代码到mexFunction,然后让matlab做循环:
data = loadData();
while(~stop) {
position = getFingerPositionMex();
soundByCoef(position, data);
}
假设您没有修改soundByCoef
内的数据,Matlab将使用传递引用,因此不会复制大型数据集。