开发区域

MATLAB高级软件开发

MATLAB讲c++

大家好!今天我想介绍一位客座博主Vivek Bhownani,他是R2019a中一个令人兴奋的新功能的首席开发人员,该功能可以轻松访问c++库,而无需编写任何c++代码。把它拿走Vivek…

在MATLAB中,您是否使用或想使用c++库?我们经常听到用户请求调用c++库,从机器学习到游戏开发。OpenCV, Tensorflow和LibXL就是一些例子。

将c++库包装以便从外部环境使用可能是一项非常耗时的任务,需要大量的开发工作。我们的目标是使您能够在不编写任何c++代码的情况下调用c++,有可能将包装一个库的工作从几天缩短到几个小时。

多年来,MATLAB通过在C接口中包装这些库并使用LOADLIBRARY提供了调用这些库的能力。MATLAB还提供了MEX接口,该接口允许您编写MATLAB包装器文件,用于调用C或c++功能。但是,每个选项都有其局限性,并且都不提供从MATLAB调用c++的直接方法。这就是为什么我对R2019a中的新功能感到兴奋,这些新功能可以帮助你从MATLAB调用c++库。MATLAB现在讲c++了!

我们的用户角色:我想通过这篇文章接触两种不同类型的用户。你是一个出版商如果你想要在MATLAB中调用某个c++库。你是一个最终用户如果您只想通过库的已发布接口调用它。

内容

调用c++不需要懂c++

我们希望帮助发布者专注于基于c++库构建应用程序。事实上,您甚至不需要了解太多c++。交给我们吧。

SWIG是一个工具,它提供了一种为c++库发布包装器接口的方法,这些库可以在包括Python和Java在内的环境中使用。但是用户需要编写专门的SWIG接口代码,用户必须学习和维护这些代码。与SWIG不同,MATLAB将尝试为您生成一个接口定义文件。然后,您可以在指定的块中编辑该文件,以根据您的需要定制接口。您不需要学习编码的特定方法。

作为最终用户,您甚至可能不需要创建接口文件——也许有人会为您编写一个。

我们鼓励你们中的一些人充当发布者,为想要与最终用户共享的图书馆创建这些接口文件。你可能是一个编写c++库的开发人员,想要接触到更广泛的受众;或者你的公司为可以用MATLAB的硬件提供驱动程序。其他发布者可能只是想分享他们的工作,以帮助其他用户调用您正在调用的c++库。作为发布者,您需要一个兼容的c++编译器。如果您是最终用户,则不需要c++编译器来调用库。

让我们看看如何调用我编写的c++类

我为一个Car with Engine的例子在c++中创建了两个类:

class Engine {private: int fNumberOfCylinders;public: Engine(int numcylinders): fNumberOfCylinders(numcylinders), isservices (false) {} int getNumCylinders() const{返回fNumberOfCylinders;} bool is已服务;};class Car {private: Engine& fEngine;public: Car(Engine &engine): fEngine(Engine) {} Engine& getEngine(){返回fEngine;}};

构建接口

由于这个库只是一个头文件,我们可以使用以下函数进行“直接”构建:

clibgen.generateLibraryDefinition (“auto.h”);构建(defineauto);
警告:只指定头文件;假设这是一个仅头文件的库。如果还需要指定库文件,则使用'Libraries'选项。警告:文件“manifest”。Json没有找到。使用Microsoft Visual c++ 2015编译器。生成定义文件` C:\BlogPost\defineauto。数据文件“C:\BlogPost\autoData.xml”包含MATLAB支持的9种构造的定义。万博1manbetx使用Build (defineauto)进行构建。构建接口文件'autoInterface.dll'。接口文件“autoInterface.dll”内置在文件夹“C:\BlogPost\auto”中。 To use the library, add the interface file folder to the MATLAB path.

您可以安全地忽略在这种情况下生成的警告。我们发出一个警告,提醒用户我们假设这是一个仅头文件的库,如果这不是准确的,那么应该使用“Libraries”选项来提供库。不要忘记将生成的文件夹“auto”(其中包含生成的接口)添加到MATLAB路径。

目录“汽车”);

好了,我们现在准备好从MATLAB调用这个库了

让我们先创造一辆带有引擎的汽车

eng = clib.auto.Engine(4);car = clib.auto.Car(eng);car.getEngine.isServiced
Ans =逻辑0

现在让我们检修一下引擎,再检查一下汽车:

eng。isservices = true;car.getEngine.isServiced
Ans =逻辑1

MATLAB创建句柄来表示c++对象。如上所示,'eng'指向汽车内部的引擎(由'car'类中的'getEngine'方法返回的对象)。但是,它不能用来破坏车内的发动机,也就是说,汽车继续拥有它的发动机。注意当我们在引擎上调用delete时。

删除eng (eng)
eng =删除引擎的句柄
car.getEngine那辆汽车(连同发动机)还完好无损。。
ans =带有属性的引擎:isserviced1

现在让我们看一个加密示例

下面是一段c++代码,它调用SpaceCrypto库中的加密算法来加密字符串“hello world!”,然后随后调用解密来获取原始字符串。

#include  #include "cryptopp_wrapper.h"使用命名空间std;int main(){//调用加密cout<<"Space Wrapper TEST!"<
           

构建接口

这里我们需要比上一个例子多做一些工作,但我们仍然不需要编写c++代码。我们有另一种构建接口的方法,这是一个多步骤过程——生成定义文件,提供定义,然后构建。

设置环境

loc =“cryptopp700”;dllLoc = fullfile(loc,“x64 \ DLL_Output \释放”);路径= getenv(“路径”);setenv (“路径”, (dllLoc“;”路径]);

生成的定义

headerFiles =“cryptopp_wrapper.h”;includePath = loc;outputFolder = pwd;Libraries = [fullfile(loc,“x64 \ DLL_Output \ \ cryptopp.lib发布”),...fullfile (loc,“x64 \ DLL_Output \ \ cryptlib.lib发布”));clibgen.generateLibraryDefinition (headerFiles“IncludePath”includePath,...“库”、图书馆、“OutputFolder”outputFolder,“PackageName”“密码”“详细”,真正的);
警告:头文件中的某些c++语言结构不受支持,不能导入。万博1manbetx使用Microsoft Visual c++ 2015编译器。生成定义文件“C:\BlogPost\definecrypto.”数据文件“C:\BlogPost\cryptoData.xml”包含MATLAB支持的20种构造的定义。万博1manbetx构造需要额外的定义。要在接口中包含这些结构,请编辑'C:\BlogPost\definecrypto.mlx'中的定义。使用Build (definecrypto)构建。

上面的步骤生成定义文件。它列出了我们在头文件中读取的所有类、函数、枚举等。

定义文件…我为什么需要它?

构建c++接口的大部分工作流程都是自动化的。MATLAB读取所提供的头文件并生成一个接口库,该接口库提供了一种调用库中每个函数/类的方法。然而,有时我们不能自动调用这样的功能,我们需要发布者帮助指定“如何调用”这样的函数(点击这里举个例子。)下面是生成文件的一个片段:

如果函数没有完全定义,则为要调用的函数提供定义。使用c++代码(如上所示)来理解需要定义哪些函数。

现在通过调用以下命令构建接口:

构建(definecrypto)
构建接口文件'cryptoInterface.dll'。接口文件“cryptoInterface.dll”内置在文件夹“C:\BlogPost\crypto”中。要使用该库,请将接口文件文件夹添加到MATLAB路径。

请注意:您需要一个c++编译器,该编译器与构建库时使用的编译器兼容。

现在我们准备在MATLAB中调用库。更重要的是,我们有一个发布者可以与最终用户共享的接口,他们不需要编译器,也不需要知道任何c++来调用库。在MATLAB中调用这个c++库就像调用任何其他MATLAB代码一样。

导入SpaceCrypto库

目录“密码”) loc =“cryptopp700”;dllLoc = fullfile(loc,“x64 \ DLL_Output \释放”);路径= getenv(“路径”);setenv (“路径”, (dllLoc“;”路径]);进口clib.crypto。*

加密原始消息

cryptObj = SpaceCrypto.CryptBlowFish;cryptObj.setPlainString (“MATLAB会讲c++ !”);%使用MATLAB字符串cryptObj.setKey (“mySecUreKey ! !”);encryptedMessage = cryptObj.Encrypt()
encryptedMessage = "3540541C31806EDD0FED2AD653A9B1EAD224D192AA281B26"

解密和检索原始消息

cryptObj = SpaceCrypto.CryptBlowFish;cryptObj.setEncString (encryptedMessage);cryptObj.setInputMode (SpaceCrypto.OUT_TYPE.HEX);% MATLAB enum for c++的enumcryptObj.setKey (“mySecUreKey ! !”);cryptObj.setOutputMode (SpaceCrypto.OUT_TYPE.NORMAL);originalMessage = cryptObj。解密
originalMessage = "MATLAB讲c++ !"

尝试连接到您自己的c++库

使用上面描述的步骤来包装要在MATLAB中调用的c++库。阅读我们的文档了解更多。在19a中,我们支持万博1manbetx很多c++ 98结构,如函数、类、方法、模板实例化和typedef。在未来,我们将提供对std::vector、智能指针、宽字符串等万博1manbetx的支持。我们还计划在MATLAB中支持c万博1manbetx++对象的自动内存管理。我们将继续改进这一功能,我想听听你们的意见。请在下方评论并告诉我们你是怎么做的,或者你认为我们下一步应该添加什么功能。我们才刚刚开始!




发布与MATLAB®R2019a

|

评论

要发表评论,请点击此处登录到您的MathWorks帐户或创建一个新帐户。