目录
附A.未找到支持的编译器或SDK,MinGW-w64 C/C++编译器在线安装
首先需明确Windows库有两种:静态库和共享库(动态库.dll)
至于如何在MATLAB里面调用DLL,以下分三步进行说明。
第一步:生成DLL注意事项
既然要调用DLL,肯定首先要有DLL这个东西。笔者通过一个例子简单介绍一下如何借助工具VisualStudio2017(Enterprise 15.9.9)生成一个DLL(基于C++)。此外,也可以在VisualC++创建DLL,只是本例使用到线程,在VisualC++中显示打不开thread对应的头文件,笔者使用的VC版本是2010,不知其它版本是否可行。根据以往经验,在VC2010添加头文件支持或许可行,如有解决方法欢迎在评论区留言。
VS2017新建动态库工程时,会自动创建两个头文件targetver.h、stdafx.h和三个源文件stdafx.cpp、dllmain.cpp、工程名.cpp。(版本不同可能会存在差异。创建时可在附加选项取消勾选预编译头,以进行自定义操作。初次使用建议保持勾选,以熟悉创建DLL对系统环境的依赖)
工程创建后,在正式编辑前,先设置平台环境(右键工程名→属性),保证与MATLAB一致(本例所用平台是64位)。一定要进入下图1所示位置进行设置,如果仅在下图1第一级窗口“Property Pages”窗口设置,最终在MATLAB里面调用时可能会报下图2、图3所示 “不是有效的win32应用程序” 和 “找不到指定的模块” 的错误提示:



本例主要是让MATLAB调用DLL启动一个线程,这个线程会以间隔4s输出两个不同的数据。VS工程命名为DllFirstTest,源文件 DllFirstTest.cpp 用于定义接口函数原型,手动创建一个头文件 Header.h,用于接口声明。各文件内容以及接口头文件的格式如下:
/*** Header.h ***/
#pragma once
#ifdef __cplusplus
extern "C"
{
#endif
__declspec(dllexport) void startThreadFunc(void);
__declspec(dllexport) int TestReturn(void);
#ifdef __cplusplus
}
#endif
/*** DllFirstTest.cpp ***/(本例还需完善)
// DllFirstTest.cpp : Defines the exported functions for the DLL application.
//
#include "stdafx.h"
#include <thread>
#include <chrono>
#include <iostream>
#include "Header.h" // 该头文件必须包含在该源文件里,否则MATLAB报 “The function ‘…’ was not found in the library.
using namespace std;
bool flag = false;
void threadFunc_1(void)
{
while (true)
{
this_thread::sleep_for(chrono::milliseconds(4000)); // 每4秒改变输出
flag ^= true;
//cout << "---threadfunc_1---" << endl; // 测试表明不能在Matlab的命令窗口打印
//printf("flag = %d", flag); // 测试表明不能在Matlab的命令窗口打印
fprintf("flag = %c", "f");
}
}
void startThreadFunc(void)
{
thread tt1(threadFunc_1);
tt1.detach();
}
int TestReturn(void)
{
if (flag)
{
return 123;
}
else
{
return 456;
}
}
编辑完成后即可build生成一个名为DllFirstTest.dll的动态库(64位在:工程目录→x64→Debug文件夹里,32位在:工程目录→Debug文件夹里)。
最后将DllFirstTest.dll、Header.h两文件拷贝到第二步创建的Simulink模型所在目录。(放其它位置需在模型对应的M函数文件中指定路径)
第二步:MATLAB中调用DLL
为了更好的视觉体验,在Simulink中创建一个MATLAB Function和一个Display,如下图所示:
MATLAB Function对应的M函数文件中需使用coder.extrinsic声明外部函数,本例需要用到的MATLAB外部函数都在以下代码中,具体含义看代码即可理解。题外话:传指针使用libpointer。
/*** M函数文件代码 ***/
% @brief Functions and Objects Supported for C/C++ DLL
% @author SLF 2019/04/06
function output = fcn
coder.extrinsic('libisloaded'); % 声明外部函数(多个函数可以逗号分隔,具体参见help)—— 这些函数在Command窗口是可以直接使用的,在M文件就需要用coder.extrinsic进行声明
% coder.extrinsic('fullfile');
coder.extrinsic('loadlibrary');
% coder.extrinsic('unloadlibrary');
coder.extrinsic('calllib');
% coder.extrinsic('libpointer');
tmp = 0; % here belong to define
% if not(libisloaded('DllFirstTest'))
if ~(libisloaded('DllFirstTest'))
% hfile = fullfile('C:\Users\XXX\Desktop\TestInterface\simulink', 'Header.h'); % dll所在位置与m文件所在位置一致即可不必指定路径
% loadlibrary('DllFirstTest', hfile);
% loadlibrary('DllFirstTest', 'Header');
loadlibrary('DllFirstTest.dll', 'Header.h');
calllib('DllFirstTest', 'startThreadFunc');
output = 0;
else
tmp = calllib('DllFirstTest', 'TestReturn'); % 456←→123
output = tmp;
% unloadlibrary('DllFirstTest');
end % if
end % function
第三步:运行MATLAB程序
如果点运行后报错,可在MATLAB的Command窗口一条一条的输入命令(最好将每条命令后的分号去掉,以打印必要的信息)。
如果用的是其他人生成的DLL,而自己电脑没有装VisualStudio,运行Simulink时MATLAB可能会报错,提示缺少以下三个文件:
ucrtbased.dll
msvcp140d.dll
vcruntime140d.dll
若遇到这样的提示,可从装有VisualStudio的电脑拷贝到Simulink模型所在目录即可。在电脑上搜索这三个文件时可能会显示多个,并有x86和x64之分,所以拷贝时需注意区别,同平台若存在多个,可以拷贝文件大小最大的。如笔者电脑是64位,MATLAB也是64位的,拷贝路径可参考如下:
C:\Program Files (x86)\Windows Kits\10\bin\10.0.17763.0\x64\ucrt\ucrtbased.dll
[VS安装路径]\2017\Enterprise\VC\Redist\MSVC\14.16.27012\debug_nonredist\x64\Microsoft.VC141.DebugCRT\msvcp140d.dll
[VS安装路径]\2017\Enterprise\VC\Redist\MSVC\14.16.27012\debug_nonredist\x64\Microsoft.VC141.DebugCRT\vcruntime140d.dll
使用MATLAB自带的外部函数注意事项一览:
附A.未找到支持的编译器或SDK,MinGW-w64 C/C++编译器在线安装
如果电脑没有装VisualStudio,运行Simulink时MATLAB可能还会报 “未找到支持的编译器或SDK”,并提示安装 MinGW-w64 C/C++编译器,如下图所示:
遇到这种情况,解决方法除了安装VS之外,还可以照提示安装MinGW-w64 C/C++编译器。往往后者更方便,因为安装VS动辄就需要至少6GB的系统盘空间,对于不常使用VS的朋友来说着实不划算。
至于MinGW-w64 C/C++的安装,笔者建议不要自行到MinGW-w64官网下载,这种方法网上虽有如何最终将其与MATLAB绑定起来,但笔者试了多种手段,均未成功。更何况MathWorks免费提供,何必舍近求远,舍易求难呢?
直接在MATLAB里面通过菜单栏 主页→环境→附加功能→获取附加功能 在线搜索MinGW-w64并下载安装,或者直接点击上图中链接Compilers - MATLAB & Simulink。如果没有MathWorks的账户,需要先注册然后登录后才会弹出一般网页下载时的下载窗口。笔者下载了一个版本供大家免注册下载(仅适用于MATLAB R2017b及以上版本):
MATLAB安装MinGW-w64C/C++编译器-IT管理文档类资源-CSDN下载
下载安装过程很简单,但为了给读者更好的理解,还是将具体过程以截图形式呈现:
第一步:鼠标点击上图命令行窗口中的链接,或者菜单栏 主页→环境→附加功能→获取附加功能 在线搜索MinGW-w64,进入下图下载页面点击“Download”
第二步:若没有MathWorks的账户,先注册然后登录,接着就会弹出自动下载窗口,操作与平时网页下载操作无异。此步下载的实际是下图所示16KB大小的文件,这应该是一个在线安装器。(若未自动弹出下载窗口,保持登录状态重新点击上一步的Download即可)
第三步:将上一步下载的mingw.mlpkginstall拖到MATLAB的命令行窗口,或者将MATLAB的当前文件夹切换到mingw.mlpkginstall所在文件夹,然后鼠标左键双击或者右键后Download and Install
第四步:接着就会自动弹出下载和安装进度界面,耐心等待即可。整个过程半个小时以内,具体视乎网速情况而定。
最后在MATLAB菜单栏 主页→环境→附加功能→管理附件功能 搜索即可看到已安装。
附B.MinGW-w64 C/C++编译器离线包安装
(笔者不想折腾了,所以未测试,仅供参考。若测试可行,欢迎评论区留言告知^_^)
在线安装后,笔者找了一下安装位置在C盘,路径可参考如下:
而安装过程自动配置的系统环境变量如下,值是C:\ProgramData\MATLAB\SupportPackages\R2017b\3P.instrset\mingw_w64.instrset
若读者正在尝试离线包配置,照以上设置后仍未成功,可试着在MATLAB命令行窗口输入setenv('MW_MINGW64_LOC','C:\ProgramData\MATLAB\SupportPackages\R2017b\3P.instrset\mingw_w64.instrset')
笔者电脑上的安装包详见附件资源:MATLABSupportforMinGW-w64C/C++Compiler.rar_matlabmingw-w64-其它文档类资源-CSDN下载
郑重提示:①本文不允许转载,若认可本文,可点赞收藏。
②若有疑问,可在评论区留言相互讨论。