c++调用matlab导出的dll及显式隐式调用
公司引入了第三方公司的算法,而第三方公司只提供matlab导出的dll,java是无法调用的,于是不得不考虑再用c++封装一层dll供java调用。
本人c++只是业余级,matlab更是路人,但公司在这方面也没什么人会,我只好继续硬着头皮开始探索之路。
环境配置
创建vc++项目后:
- 右键项目 - 属性 - VC++目录 - 包含目录,添加..\MATLAB\MATLAB Runtime\v90\extern\include
- 库目录添加:..\MATLAB\MATLAB Runtime\v90\extern\lib\win64\microsoft
- 链接器 - 输入 - 附加依赖项,添加以下几个lib:
mclmcr.lib
mclmcrrt.lib
libmx.lib
libmex.lib
libmat.lib
libeng.lib

c++调用matlib的dll.jpg
DLL调用
调用matlab的dll大概分为三个过程,1. 初始化Initialize 2. 调用功能函数 3. 终止Terminate
显式调用
在c++中,dll的调用分为显式和隐式,显示调用的好处是只需要知道dll和里面的函数即可完成调用,不需要.h文件和.lib文件,以下是显示调用的实例
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 |
<span class="hljs-meta">#<span class="hljs-meta-keyword">include</span><span class="hljs-meta-string"><iostream></span></span> <span class="hljs-meta">#<span class="hljs-meta-keyword">include</span> <span class="hljs-meta-string">"windows.h"</span></span> <span class="hljs-function"><span class="hljs-keyword">void</span> <span class="hljs-title">test</span><span class="hljs-params">()</span> </span>{ <span class="hljs-comment">// 加载dll</span> HINSTANCE testDLL = LoadLibraryA(<span class="hljs-string">"TestDLL.dll"</span>); <span class="hljs-comment">// 包含一个Add函数</span> <span class="hljs-comment">//TestDLL初始化函数</span> <span class="hljs-function"><span class="hljs-keyword">typedef</span> <span class="hljs-title">bool</span><span class="hljs-params">(*pInitialize)</span><span class="hljs-params">(<span class="hljs-keyword">void</span>)</span></span>;<span class="hljs-comment">//初始化函数</span> pInitialize Initialize = <span class="hljs-literal">NULL</span>; Initialize = (pInitialize)GetProcAddress(testDLL, <span class="hljs-string">"TestInitialize"</span>);<span class="hljs-comment">//TestInitialize函数声明在.h文件里面</span> <span class="hljs-keyword">if</span> (Initialize()) <span class="hljs-comment">//初始化,成功后才进入后续调用</span> { <span class="hljs-comment">//TestDLL功能函数</span> <span class="hljs-function"><span class="hljs-keyword">typedef</span> <span class="hljs-title">int</span><span class="hljs-params">(*pAdd)</span><span class="hljs-params">(<span class="hljs-keyword">int</span> num1, <span class="hljs-keyword">int</span> num2)</span></span>; pAdd Add = <span class="hljs-literal">NULL</span>; Add = (pAdd)GetProcAddress(testDLL, <span class="hljs-string">"Add"</span>);<span class="hljs-comment">//Add函数声明在.h文件里面</span> <span class="hljs-keyword">int</span> sum = Add(<span class="hljs-number">1</span>, <span class="hljs-number">1</span>); <span class="hljs-built_in">std</span>::<span class="hljs-built_in">cout</span> << <span class="hljs-string">" Add(1, 1) = "</span> + sum << <span class="hljs-built_in">std</span>::<span class="hljs-built_in">endl</span>; <span class="hljs-comment">//TestDLL结束函数</span> <span class="hljs-function"><span class="hljs-keyword">typedef</span> <span class="hljs-title">void</span><span class="hljs-params">(*pTerminate)</span><span class="hljs-params">(<span class="hljs-keyword">void</span>)</span></span>; pTerminate Terminate = <span class="hljs-literal">NULL</span>; Terminate = (pTerminate)GetProcAddress(testDLL, <span class="hljs-string">"TestTerminate"</span>);<span class="hljs-comment">//TestTerminate函数声明在.h文件里面</span> Terminate(); } <span class="hljs-comment">// 释放dll</span> FreeLibrary(testDLL); } |
隐式调用
隐式调用则需要.h文件和.lib文件,将头文件导入项目中,然后使用以下代码实现,还是相同的三个方法,隐式调用需要处理头文件,比显示调用麻烦,但是代码上比显示看上去简洁(也许是因为我的demo比较简单)
1 2 3 4 5 6 7 8 9 10 11 12 13 |
<span class="hljs-meta">#<span class="hljs-meta-keyword">include</span><span class="hljs-meta-string"><iostream></span></span> <span class="hljs-meta">#<span class="hljs-meta-keyword">include</span> <span class="hljs-meta-string">"TestDLL.h"</span> <span class="hljs-comment">// 一般会在test.h中include该头文件,然后只需导入test.h即可</span></span> <span class="hljs-meta">#<span class="hljs-meta-keyword">pragma</span> comment(lib, <span class="hljs-meta-string">"TestDLL"</span>)</span> <span class="hljs-function"><span class="hljs-keyword">void</span> <span class="hljs-title">test</span><span class="hljs-params">()</span> </span>{ <span class="hljs-keyword">if</span> (TestInitialize()) <span class="hljs-comment">//初始化,成功后才进入后续调用</span> { <span class="hljs-keyword">int</span> sum = Add(<span class="hljs-number">1</span>, <span class="hljs-number">1</span>); <span class="hljs-comment">// 功能函数</span> <span class="hljs-built_in">std</span>::<span class="hljs-built_in">cout</span> << <span class="hljs-string">" Add(1, 1) = "</span> + sum << <span class="hljs-built_in">std</span>::<span class="hljs-built_in">endl</span>; TestTerminate(); <span class="hljs-comment">// 终止</span> } } |
原文:简书ThinkinLiu 博客: IT老五
常见问题
1. dll找不到
如果是相对目录,是相对于你所见的项目目录而言的,放在在项目目录下即可
2. Initialize初始化报错
这个一般是matlab环境问题或者是加载不到dll导致的