在MATLAB中调用封装的C/C++的共享库(dll文件)的解决方法

  • Post author:
  • Post category:其他

这是个痛苦的故事。。。。。。工作需要,加油吧打工人哈哈哈哈哈
废话少说正文开始。

想要再MATLAB中调用dll,需要先了解几个函数(不想了解也无所谓,可以直接跳过):
————————————————————————————————————————————————————————————

函数名 含意
loadlibrary 将 C 共享库加载到 MATLAB
unloadlibrary 从内存中卸载共享 C 库
calllib 调用 C 共享库中的函数
libfunctions 返回 C 共享库中函数的信息
libfunctionsview 在窗口中显示 C 共享库函数签名
libisloaded 确定是否已加载 C 共享库
libpointer 用于 C 共享库的指针对象
libstruct 将 MATLAB 结构体转换为 C 样式的结构体以用于 C 共享库

(以上为C库,详见Mathworks官网,或者直接MATLAB一个help,你懂的。)

函数名 含意
clibArray 为 C++ 数组或 std::vector 创建 MATLAB 对象
clibConvertArray 对于 C++ 数组,将数值数组转换为 MATLAB 对象
clibIsNull 确定 C++ 对象是否为空
clibIsReadOnly 确定 C++ 对象是否为只读
clibRelease 从 MATLAB 中释放 C++ 对象
underlyingValue 在 MATLAB 中创建的 C++ 枚举对象的基础数值
clibgen.generateLibraryDefinition 为 C++ 库创建定义文件
clibgen.buildInterface 在没有定义文件的情况下创建 C++ 库的接口

以上为C++库。
以上内容详见:mathworks官网
————————————————————————————————————————————————————————————
跳转截至这里,我们继续看。
既然要调用dll,必然需要有一个dll,所以我们需要写一个dll。
本文用到的工具:MATLAB R2020a,Microsoft Visual Studio 2015社区版,windows自带的文件管理器。

1.建立一个dll文件。
启动Microsoft Visual Studio 2015社区版(请确保您安装了相关的C++的编译工具),点击新建项目,然后再Visual C++的Win32选项选择WIN32控制台应用程序,输入你的名称和位置,点击确认,如图所示。
在这里插入图片描述
在这里插入图片描述
然后点击下一步,在弹出的窗口继续点击下一步,如图所示。
在这里插入图片描述
在这个窗口我们修改应用程序类型为DLL,其他保持默认,点击完成,如下图所示。
在这里插入图片描述
在这里插入图片描述
这个时候我们要了解一下这个工程文件的内容(现在我也不是很懂这个结构的细节,大神勿喷,有错误请指出,必改)

在上图的右侧可以看到解决方案“matlab_c”(1个项目)的字样,然后下面有“引用”/‘外部依赖项’/‘头文件’/‘源文件’/‘资源文件’这几个板块,我们需要用到的是头文件(后缀为.h)和源文件(后缀为.cpp)。我们的函数可以写在源文件,然后再头文件中进行扩展定义。

先点击matlab_c.cpp,弹出了代码编辑界面,这里采用C++书写代码即可,在下图所示,保持原来的代码不变,在下面书写函数,但是要在预定义部分包含一个头文件(图片中被红色波浪线标记出来的位置,提示无法打开源文件xxx.h,是因为我们还没有创建这个文件),接下来要把我们的函数在头文件中预定义。在这里我的头文件名为matlab_c.h,大家可以自己设计喜欢的头文件名,但是后缀应当是.h。

// mathlab_c.cpp : 定义 DLL 应用程序的导出函数。
//

#include "stdafx.h"

#include "matlab_c.h"

double add(double x, double y)
{
	return (x + y);
}

double minus(double x, double y)
{
	return (x - y);
}

在这里插入图片描述
接下来创建头文件,在“头文件”三个字处右键,选择添加,然后点击新建项,如左下图所示。在这里插入图片描述
然后再新弹出的窗口选择头文件选项,然后记得修改下面的名称,位置不要修改,名称改为刚刚cpp文件中写的头文件的名称即可,如下图,我的头文件名为matlab_c.h,随后点击添加。
在这里插入图片描述
之后软件会自动打开头文件的编辑见面,但是默认有一行代码是#pragma once,强烈建议把他删了(要是没有当我没说),我恨死他了。
接下来我们来写头文件。头文件稍微复杂一点,所以感兴趣的同学去百度一下“ifndef”啥的的作用,我就不介绍了,比毕竟我也是刚百度的…
值得注意的是千万不要忘记extern “C”,不然你这C++语言MATLAB可不认识的。
中间两行蓝色的是定义函数的,前面的__declspec(dllexport) 是说要搞dll革命,后面的double minus(double x, double y)是说这个函数要搞革命,反正哪个家伙革命你单独把他摆在这里就ok,毕竟你的文件里面未必所有的家伙都要搞革命(被matlab调用)吧。

#ifndef MATLAB_C_H
#define MATLAB_C_H

//上面的代码只要把MATLAB_C_H替换成你头文件名称的大写就ok(.要换成_)

#ifdef __cplusplus
extern "C"
{
#endif
	//上面的代码是必须要有的

	__declspec(dllexport) double add(double x, double y);
	__declspec(dllexport) double minus(double x, double y);

	//上面的代码是用来定义函数的,可以简单理解为告诉MATLAB你有什么函数
	//下面的代码也是必须要有的别管为什么问就是去百度
#ifdef __cplusplus
}
#endif
#endif

在这里插入图片描述

好了,至此,我们就搞定了简单的一个函数了,这个函数可以实现加法和减法。让我们来编译它吧!
为了不必要的麻烦,请这样操作(别问为什么,干就完了):

对这个项目文件右键,弹出的窗口选择属性,如下图。
在这里插入图片描述
然后再弹出的窗口里面,把你的配置属性-C/C++,然后点代码生成,把那个运行库换成多线程调试(/MTd),注意不是多线程调试DLL(/MDd),然后反手给个确定。
累了吗?不要急,生成dll最后一步了,马上结束!!!!!!
看到最上面这个工具栏了吧,把这个x86改成x64,点击生成,弹出的下拉框选择生成matlab_c(U),注意可能由于文件名不一样导致这个不一样但是不必担心,生成就完事了。
在这里插入图片描述
在这里插入图片描述
如果顺利的话,你会看到:
1>—— 已启动生成: 项目: mathlab_c, 配置: Debug x64 ——
1> stdafx.cpp
1> dllmain.cpp
1> mathlab_c.cpp
1> 正在创建库 C:\Users\runner\Desktop\matlab_c\mathlab_c\x64\Debug\mathlab_c.lib 和对象 C:\Users\runner\Desktop\matlab_c\mathlab_c\x64\Debug\mathlab_c.exp
1> mathlab_c.vcxproj -> C:\Users\runner\Desktop\matlab_c\mathlab_c\x64\Debug\mathlab_c.dll
1> mathlab_c.vcxproj -> C:\Users\runner\Desktop\matlab_c\mathlab_c\x64\Debug\mathlab_c.pdb (Full PDB)
========== 生成: 成功 1 个,失败 0 个,最新 0 个,跳过 0 个 ==========
在这里插入图片描述

到此为止,我们的dll文件正式搞定了!接下来你的Microsoft Visual Studio 2015社区版就可以关掉了。(卸磨杀驴有点狠但是它吃我内存我说啥了是不是)
在这里插入图片描述

2.建立MATLAB所需要的dll文件库。
现在启动你的文件管理器找到你的这个工程文件所在地(别告诉我你忘记他在哪了,要是忘记了就回去重新来过!!!),点击x64,然后点击Debug文件夹。在这里插入图片描述

看到这几个鬼鬼祟祟的家伙没有,我们要的就是这个后缀是dll的文件,这就是我们搞了这么久搞出来的dll文件,但是光有他还不够。在这里插入图片描述

再回到你的工程文件目录,这次进matlab_c里面,有个matlab_c.h的,这个就是我们写的头文件,他也得有。其他的嘛。。。。。无所谓了,先不管吧。
在这里插入图片描述

好,我们现在新建一个文件夹作为我们MATLAB的运行目录,然后把这俩家伙给他丢进去。
然后启动你的MATLAB!
在这里插入图片描述
然后修改一下当前文件夹到我们刚刚设置的那个目录,我的目录文件夹名字叫MATLAB运行环境,当然你随便起名字,无所谓,哪怕你叫他王者荣耀都ok。
在这里插入图片描述
3.测试我们的程序。
激动人心的时刻到了!
还记得我们最开始说的那几个代码吗?来和我复习一下:

函数名 含意
loadlibrary 将 C 共享库加载到 MATLAB
unloadlibrary 从内存中卸载共享 C 库
calllib 调用 C 共享库中的函数
libfunctions 返回 C 共享库中函数的信息
libfunctionsview 在窗口中显示 C 共享库函数签名
libisloaded 确定是否已加载 C 共享库
libpointer 用于 C 共享库的指针对象
libstruct 将 MATLAB 结构体转换为 C 样式的结构体以用于 C 共享库

好的,我们先把这个C 共享库加载到 MATLAB。
为了省事我就直接再命令行敲了,如果我们写代码的话,还是建议写成脚本文件。
(忽然发现我写代码的时候把matlab写成了mathlab。。。。如果你们是正确的就正常来,如果是和我一样搞错了就将错就错吧…)

%加载库
loadlibrary('mathlab_c.dll','matlab_c.h')
%判断是否加载成功
libisloaded('mathlab_c')

在这里插入图片描述
看看这个库有什么函数可以用:

libfunctions('mathlab_c')

在这里插入图片描述
调用add和minus进行计算:

calllib('mathlab_c', 'add', 5.20, 13.14)

在这里插入图片描述

calllib('mathlab_c', 'minus', 5.20, 13.14)

在这里插入图片描述
卸载库并判断是否卸载完成:

%卸载库
unloadlibrary 'mathlab_c'
%判断库是否加载
libisloaded('mathlab_c')
%ans=0说明没有加载

在这里插入图片描述
4.至此,教程完毕!

如果本教程对您有用,点个赞吧~


版权声明:本文为qq_42818011原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。