我正在尝试将一个外部的基于FORTRAN的DLL(使用Intel Fortran编译器编译)包含到MATLAB中。由于它是外部的,我不能对DLL的运行时库进行任何调整。目前,我编写了一个C++的附带头文件来调用DLL。使用
我认为以下原因可能导致此问题,但由于我在使用DLL方面缺乏经验(特别是在C++编码方面),我尚未自己找到错误。
loadlibrary
函数,库被加载到MATLAB中(没有错误 - 只有一个警告),但是,在使用calllib
函数时,MATLAB会崩溃并且不提供错误信息。我认为以下原因可能导致此问题,但由于我在使用DLL方面缺乏经验(特别是在C++编码方面),我尚未自己找到错误。
- 还有一个.lib文件,我从供应商那里得到了这个文件,但我还没有将其合并到MATLAB文件或C++头文件中。
FILEA
和FILEB
变量是指两个输入到DLL中的文本文件的路径,我认为我可能没有正确地将它们合并到C++中。- 在
mHeader
文件(MATLAB头文件)中,stdcall
只在注释部分中提到,并未在编码部分中提到。
#ifndef _MYMODEL
#define _MYMODEL
#ifdef __cplusplus
extern "C" {
#endif // _cplusplus
// Functions and data types defined
void __stdcall MYFUN(char FILEA[], char FILEB[], int *IDTask, int
*nErrorCode, int *ErrorCode, double *Props, double *Out1, double *Out2,
double *Out3, double *Out4, double *Out5);
#ifdef __cplusplus
}
#endif // __cplusplus
#endif // !_MYMODEL
MATLAB (r2018b):
%% Input to model
FILEA = 'PATH\FILEA.txt';
FILEB = 'PATH\FILEB.txt';
IDTask = 1; %Multiple tasks possible in the .dll
%% Determine pointers
lpFILEA = libpointer('cstring', FILEA);
lpFILEB = libpointer('cstring', FILEB);
lpIDTask = libpointer('int32Ptr', IDTask);
lpnErrorCode = libpointer('int32Ptr');
lpErrorCode = libpointer('int32Ptr');
lpProps = libpointer('doublePtr');
lpOut1 = libpointer('doublePtr');
lpOut2 = libpointer('doublePtr');
lpOut3 = libpointer('doublePtr');
lpOut4 = libpointer('doublePtr');
lpOut5 = libpointer('doublePtr');
%% LoadLibrary
[notfound, warnings] = loadlibrary('MYMODEL.dll','MYMODEL.h' ,'mfilename', 'mHeader');
%% Call .dll
[~,~, ~, nErrorOut, ErrorCodeOut, PropsOut, Out1_, ~, ~, Out4_, Out5_] ...
= calllib('MYMODEL', 'MYFUN', lpFILEA, ...
lpFILEB, lpIDTask, lpnErrorCode, lpErrorCode, lpProps, lpOut1, ...
lpOut2, lpOut3, lpOut4, lpOut5);
Thanks in advance for your help!
calllib
函数之前设置断点。然后,如果dll
具有调试符号,即它是在调试模式下编译而不是发布模式下编译的,你就可以步进代码了。我记得5~6年前我为一个从Matlab调用的C语言mex文件做过这个操作。我不确定是否对dll
文件也适用。 - Duck Dodgerswalk the code
来定位代码工作良好的位置,跟踪线可以输出到文本文件中。我知道这看起来很原始,但当其他方法都不起作用时,这就是唯一的方法。 - Duck Dodgers