MATLAB混合编程——MATLAB中调用动态链接库DLL、未找到支持的编译器或SDK、MinGW-w64 C/C++编译器安装_matlab support for mingw-w64 c/c++ compiler-程序员宅基地

技术标签: MinGW-w64 C/C++编译器  未找到支持的编译器或SDK  VS生成DLL  MATLAB混合编程  MATLAB调用DLL  传经送宝  


目录

第一步:生成DLL注意事项

第二步:MATLAB中调用DLL

第三步:运行MATLAB程序

附A.未找到支持的编译器或SDK,MinGW-w64 C/C++编译器在线安装

附B.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应用程序” 和 “找不到指定的模块” 的错误提示:

图1
图2
图3

本例主要是让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下载

    

郑重提示:①本文不允许转载,若认可本文,可点赞收藏。

                      ②若有疑问,可在评论区留言相互讨论。

版权声明:本文为博主原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。
本文链接:https://blog.csdn.net/jiqiren_dasheng/article/details/103759720

智能推荐

什么是内部类?成员内部类、静态内部类、局部内部类和匿名内部类的区别及作用?_成员内部类和局部内部类的区别-程序员宅基地

文章浏览阅读3.4k次,点赞8次,收藏42次。一、什么是内部类?or 内部类的概念内部类是定义在另一个类中的类;下面类TestB是类TestA的内部类。即内部类对象引用了实例化该内部对象的外围类对象。public class TestA{ class TestB {}}二、 为什么需要内部类?or 内部类有什么作用?1、 内部类方法可以访问该类定义所在的作用域中的数据,包括私有数据。2、内部类可以对同一个包中的其他类隐藏起来。3、 当想要定义一个回调函数且不想编写大量代码时,使用匿名内部类比较便捷。三、 内部类的分类成员内部_成员内部类和局部内部类的区别

分布式系统_分布式系统运维工具-程序员宅基地

文章浏览阅读118次。分布式系统要求拆分分布式思想的实质搭配要求分布式系统要求按照某些特定的规则将项目进行拆分。如果将一个项目的所有模板功能都写到一起,当某个模块出现问题时将直接导致整个服务器出现问题。拆分按照业务拆分为不同的服务器,有效的降低系统架构的耦合性在业务拆分的基础上可按照代码层级进行拆分(view、controller、service、pojo)分布式思想的实质分布式思想的实质是为了系统的..._分布式系统运维工具

用Exce分析l数据极简入门_exce l趋势分析数据量-程序员宅基地

文章浏览阅读174次。1.数据源准备2.数据处理step1:数据表处理应用函数:①VLOOKUP函数; ② CONCATENATE函数终表:step2:数据透视表统计分析(1) 透视表汇总不同渠道用户数, 金额(2)透视表汇总不同日期购买用户数,金额(3)透视表汇总不同用户购买订单数,金额step3:讲第二步结果可视化, 比如, 柱形图(1)不同渠道用户数, 金额(2)不同日期..._exce l趋势分析数据量

宁盾堡垒机双因素认证方案_horizon宁盾双因素配置-程序员宅基地

文章浏览阅读3.3k次。堡垒机可以为企业实现服务器、网络设备、数据库、安全设备等的集中管控和安全可靠运行,帮助IT运维人员提高工作效率。通俗来说,就是用来控制哪些人可以登录哪些资产(事先防范和事中控制),以及录像记录登录资产后做了什么事情(事后溯源)。由于堡垒机内部保存着企业所有的设备资产和权限关系,是企业内部信息安全的重要一环。但目前出现的以下问题产生了很大安全隐患:密码设置过于简单,容易被暴力破解;为方便记忆,设置统一的密码,一旦单点被破,极易引发全面危机。在单一的静态密码验证机制下,登录密码是堡垒机安全的唯一_horizon宁盾双因素配置

谷歌浏览器安装(Win、Linux、离线安装)_chrome linux debian离线安装依赖-程序员宅基地

文章浏览阅读7.7k次,点赞4次,收藏16次。Chrome作为一款挺不错的浏览器,其有着诸多的优良特性,并且支持跨平台。其支持(Windows、Linux、Mac OS X、BSD、Android),在绝大多数情况下,其的安装都很简单,但有时会由于网络原因,无法安装,所以在这里总结下Chrome的安装。Windows下的安装:在线安装:离线安装:Linux下的安装:在线安装:离线安装:..._chrome linux debian离线安装依赖

烤仔TVの尚书房 | 逃离北上广?不如押宝越南“北上广”-程序员宅基地

文章浏览阅读153次。中国发达城市榜单每天都在刷新,但无非是北上广轮流坐庄。北京拥有最顶尖的文化资源,上海是“摩登”的国际化大都市,广州是活力四射的千年商都。GDP和发展潜力是衡量城市的数字指...

随便推点

java spark的使用和配置_使用java调用spark注册进去的程序-程序员宅基地

文章浏览阅读3.3k次。前言spark在java使用比较少,多是scala的用法,我这里介绍一下我在项目中使用的代码配置详细算法的使用请点击我主页列表查看版本jar版本说明spark3.0.1scala2.12这个版本注意和spark版本对应,只是为了引jar包springboot版本2.3.2.RELEASEmaven<!-- spark --> <dependency> <gro_使用java调用spark注册进去的程序

汽车零部件开发工具巨头V公司全套bootloader中UDS协议栈源代码,自己完成底层外设驱动开发后,集成即可使用_uds协议栈 源代码-程序员宅基地

文章浏览阅读4.8k次。汽车零部件开发工具巨头V公司全套bootloader中UDS协议栈源代码,自己完成底层外设驱动开发后,集成即可使用,代码精简高效,大厂出品有量产保证。:139800617636213023darcy169_uds协议栈 源代码

AUTOSAR基础篇之OS(下)_autosar 定义了 5 种多核支持类型-程序员宅基地

文章浏览阅读4.6k次,点赞20次,收藏148次。AUTOSAR基础篇之OS(下)前言首先,请问大家几个小小的问题,你清楚:你知道多核OS在什么场景下使用吗?多核系统OS又是如何协同启动或者关闭的呢?AUTOSAR OS存在哪些功能安全等方面的要求呢?多核OS之间的启动关闭与单核相比又存在哪些异同呢?。。。。。。今天,我们来一起探索并回答这些问题。为了便于大家理解,以下是本文的主题大纲:[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-JCXrdI0k-1636287756923)(https://gite_autosar 定义了 5 种多核支持类型

VS报错无法打开自己写的头文件_vs2013打不开自己定义的头文件-程序员宅基地

文章浏览阅读2.2k次,点赞6次,收藏14次。原因:自己写的头文件没有被加入到方案的包含目录中去,无法被检索到,也就无法打开。将自己写的头文件都放入header files。然后在VS界面上,右键方案名,点击属性。将自己头文件夹的目录添加进去。_vs2013打不开自己定义的头文件

【Redis】Redis基础命令集详解_redis命令-程序员宅基地

文章浏览阅读3.3w次,点赞80次,收藏342次。此时,可以将系统中所有用户的 Session 数据全部保存到 Redis 中,用户在提交新的请求后,系统先从Redis 中查找相应的Session 数据,如果存在,则再进行相关操作,否则跳转到登录页面。此时,可以将系统中所有用户的 Session 数据全部保存到 Redis 中,用户在提交新的请求后,系统先从Redis 中查找相应的Session 数据,如果存在,则再进行相关操作,否则跳转到登录页面。当数据量很大时,count 的数量的指定可能会不起作用,Redis 会自动调整每次的遍历数目。_redis命令

URP渲染管线简介-程序员宅基地

文章浏览阅读449次,点赞3次,收藏3次。URP的设计目标是在保持高性能的同时,提供更多的渲染功能和自定义选项。与普通项目相比,会多出Presets文件夹,里面包含着一些设置,包括本色,声音,法线,贴图等设置。全局只有主光源和附加光源,主光源只支持平行光,附加光源数量有限制,主光源和附加光源在一次Pass中可以一起着色。URP:全局只有主光源和附加光源,主光源只支持平行光,附加光源数量有限制,一次Pass可以计算多个光源。可编程渲染管线:渲染策略是可以供程序员定制的,可以定制的有:光照计算和光源,深度测试,摄像机光照烘焙,后期处理策略等等。_urp渲染管线

推荐文章

热门文章

相关标签