在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) #endifMsgBox.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打开
导出的函数名很明显是c++风格的。看下这种接口是否能被加载(把头文件和dll拷到matlab工作目录下):
看来是加载了,不能调用指定函数所以失败了。
那怎样生成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的接口:
嗯,有点像C风格的接口了,看下调用结果
终于弹出对话框了。
完
后记,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)