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类型动态库_第1张图片
导出的函数名很明显是c++风格的。看下这种接口是否能被加载(把头文件和dll拷到matlab工作目录下):

MATLAB调用非MEX类型动态库_第2张图片

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

那怎样生成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类型动态库_第3张图片

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

MATLAB调用非MEX类型动态库_第4张图片

终于弹出对话框了。


后记,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)


你可能感兴趣的:(matlab)