C++调用matlab编译的动态链接库dll

Matlab在语法上具有诸多的便利性,可以把matlab的代码(.m文件)为动态链接库dll,之后在c++中调用。本文讲解如何操作以及一些细节。

测试环境:

  • 操作系统:windows10
  • C++:visual studio 2017
  • Matlab版本:Matlab R2020b

Matlab代码编译dll

第一步:编写matlab代码。这里以计算标量与向量的乘积为例。选用该实例的原因是为了演示C++调用matlab的函数时如何返回数组。

function [c]=example(a,v)
%v为一个向量
%a为double
%函数返回标量与向量的乘积
num=length(v);
c=zeros(1,num);
   for i=1:num
     c(i)=a*v(i);  
   end
end

第二步:配置编译环境。在matlab的命令行窗口中输入mbuild -setup,matlab会自动搜索系统安装的vs编译环境。点击其中的Microsoft Visual C++ 2017 (C) 和mex -setup C++ -client MBUILD 配置好环境。

>> mbuild -setup
MBUILD 配置为使用 'Microsoft Visual C++ 2017 (C)' 以进行 C 语言编译。

要选择不同的 C 编译器,请从以下选项中选择一种命令:
Microsoft Visual C++ 2017 (C)  mex -setup:C:\Users\wanyz\AppData\Roaming\MathWorks\MATLAB\R2020b\MBUILD_C_win64.xml C -client MBUILD
Microsoft Visual C++ 2019 (C)  mex -setup:'C:\Program Files\Polyspace\R2020b\bin\win64\mexopts\msvc2019.xml' C -client MBUILD

要选择不同的语言,请从以下选项中选择一种命令:
 mex -setup C++ -client MBUILD 
 mex -setup FORTRAN -client MBUILD

第三步: 编译matlab的代码为动态链接库。在matlab的命令行窗口中输入deploytool命令,打开matlab compiler,选择Library Compiler。

在弹出的窗口的TYPE中选中C++Shared Library,在EXPORTED FUNCTIONS中选中写好的example.m文件,接着点击Package按钮。注意一定要选中example.m文件。

 

如果没有错误,将打包成功。硬盘上将生成三个文件夹:for_redistribution、for_redistribution_files_only和for_testing。其中for_redistribution_files_only是需要使用的文件,包含编译好的lib文件、h文件和dll文件,即example.h、example.lib和example.dll。

 

C++调用matlab的dll

第一步:新建C++的控制台程序,选择64位解决方案,配置好包含文件和库文件的路径。

  • 包含目录:C:\Program Files\Polyspace\R2020b\extern\include; ../../for_redistribution_files_only
  • 库目录:C:\Program Files\Polyspace\R2020b\extern\lib\win64\microsoft;../../for_redistribution_files_only

第二步:链接器->输入->附加依赖项,添加如下库文件:example.lib和mclmcrrt.lib

第三步:编写C++调用代码。我们打开生成的example.h文件看看接口函数:

extern LIB_example_CPP_API void MW_CALL_CONV example(int nargout, mwArray& c, const mwArray& a, const mwArray& v);

 从上述接口函数我们可以看出:

  • 函数返回的是void,跟我们matlab定义的返回数组不同
  • 函数的参数比我们原matlab代码多了两个,即第一个int nargout和mwArray& c。此处的mwArray是一个c++的类,可以理解为数组。多了的这两个参数即是定义函数的返回值。其中mwArray& c是引用的方式传递的,即外部传入的值在函数内部会修改。int nargout则表示返回值的个数。注意该个数不是mwArray& c这个数组的大小,而是表示返回多少值。由于matlab的函数可以返回多个值,而C++的函数只能返回一个值,所以经过转换以后,会将所有的返回值都引用参数的方式放在函数中,int nargout即表示原始matlab代码返回多少个值。
  • 原始matlab代码中的参数全部边为了mwArray类型

代码运行的顺序:

  • 第一步:调用mclInitializeApplication进行程序初始化。
  • 第二步:调用exampleInitialize进行初始化。此处的函数名根据前边命名不同而不同
  • 第三步:调用dll中的函数进行计算,保存返回的结果
  • 第四步:调用mclTerminateApplication函数终止程序

按照上述逻辑,调用代码如下:

#include <iostream>
#include "example.h"
int main()
{
	//初始化
	if (!mclInitializeApplication(NULL, 0))//程序初始化
	{
		std::cout << "failed" << std::endl;
		return -1;
	}	
	exampleInitialize();//函数初始化

	//创建输入参数
	mwArray a(1, 1, mxDOUBLE_CLASS);//创建1*1的double型数组,作为函数的第三个参数(原matlab代码的第一个参数)
	a(1, 1) = 2;
	mwArray v(1, 2, mxDOUBLE_CLASS);//创建1*2的double型数组,作为函数的第四个参数(原matlab代码的第二个参数)
	double v_c[] = { 1,2 };
	v.SetData(v_c, 1*2);//使用SetData为数组赋值,第二个参数为数组的元素个数,即1*2

	mwArray c(1, 2, mxDOUBLE_CLASS);//创建1*2的double数组,作为函数的第二个参数(原matlab代码的返回值)
	int nargout = 1;//定义返回值的个数,原matlab代码只返回一个值,这里设置为1

	//调用dll中的函数计算
	example(nargout, c, a, v);
	//输出计算结果。计算结果保存在c中,注意数组与matlab一样从1开始
	std::cout << "Result = (" << c(1, 1) << "," << c(1, 2) << ")" << std::endl;

	//终止程序
	mclTerminateApplication();
}

 上述代码计算标量2与向量(1,2)的乘积,计算结果如下:

 以上即是使用c++调用maltab动态库中函数的方法。

 

  • 0
    点赞
  • 8
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值