0
点赞
收藏
分享

微信扫一扫

MATLAB调用非MEX类型动态库


    在matlab命令行下调用现有的动态连接库即Dll文件,即非MEX文件。因为DLL的编写者生成该dll时未必想到以后会被Matlab调用,所以未必会有mexFunction入口。但是这样的动态连接库占多数,因此知道调用方法还是必要的。

    Matlab加载并调用,关闭Dll通过loadlibrary/calllib/unloadlibrary

    一般在windows下开发DLL程序使用的都是vc++6.0及其后版本。虽然在工程向导里有生成Dll的步骤,但是,通过那种默认方式生成的Dll接口是针对C++的,Matlab载入该dll后不能直接调用,得生成c语言类型接口。

    比如要创建一个名为MsgBox.dll的动态连接库,其导出唯一的一个接口matMessageBox。用vc++6默认生成的代码如下:

MsgBox.h文件

#ifdef MSGBOX_EXPORTS
#define MSGBOX_API __declspec(dllexport)
#else
#define MSGBOX_API __declspec(dllimport)
#endif

MsgBox.c文件

#include "MsgBox.h"
#include <windows.h>
BOOL APIENTRY DllMain( HANDLE hModule,
DWORD ul_reason_for_call,
LPVOID lpReserved
)
{
switch (ul_reason_for_call)
{
case DLL_PROCESS_ATTACH:
case DLL_THREAD_ATTACH:
case DLL_THREAD_DETACH:
case DLL_PROCESS_DETACH:
break;
}
return TRUE;
}

MSGBOX_API unsigned int matMessageBox(char* caption,char* contain,unsigned int type)
{
::MessageBox(NULL,caption,contain,type);
return 0;
}

编译后生成的Dll文件用Dependency打开

MATLAB调用非MEX类型动态库_matlab


导出的函数名很明显是c++风格的。看下这种接口是否能被加载(把头文件和dll拷到matlab工作目录下):

MATLAB调用非MEX类型动态库_#endif_02

看来是加载了,不能调用指定函数所以失败了。

那怎样生成C语言接口的DLL?

很简单,声明函数时,加上extern "C",具体extern "C"的作用是啥还得问隔壁百度

修改后的头文件(仅修改头文件声明即可,cpp不用修改)

#ifdef MSGBOX_EXPORTS
#define MSGBOX_API __declspec(dllexport)
#else
#define MSGBOX_API __declspec(dllimport)
#endif

#ifdef __cplusplus
extern "C" {
#endif

MSGBOX_API unsigned int matMessageBox(char*,char*,unsigned int);

#ifdef __cplusplus
}
#endif

看下这时生成的DLL的接口:

MATLAB调用非MEX类型动态库_#endif_03

嗯,有点像C风格的接口了,看下调用结果

MATLAB调用非MEX类型动态库_#ifdef_04

终于弹出对话框了。

后记,C语言的参数少不了有指针类型,就像这里的MsgBox封装了WinAPI MessageBox,该函数第一个参数就是void*类型。如何传入指针类型参数?可参考Matlab帮助文档:

External Interfaces-Matlab Interface to Generic DLLS-Data Conversion章节

这里给出一个简单例子

还是MsgBox,不过这次要传入指针参数:

#ifdef MSGBOX_EXPORTS
#define MSGBOX_API __declspec(dllexport)
#else
#define MSGBOX_API __declspec(dllimport)
#endif

#include <windows.h>

#ifdef __cplusplus
extern "C"
{
#endif

MSGBOX_API unsigned int matMessageBox(HANDLE,char*,char*,unsigned int);

#ifdef __cplusplus
}
#endif

在matlab中的调用方法:

>> loadlibrary('MsgBox.dll','MsgBox.h')
>> hnd=0;
>> hndPtr=libpointer('int32Ptr',hnd)
>> calllib('MsgBox','matMessageBox',hndPtr,'123','456',0)



举报

相关推荐

0 条评论