尝试重现问题,我已经为您的情况编写了一个最小工作示例:一个MEX文件,链接到动态库并使用其公开的函数之一。我已经在WinXP 32位上使用MATLAB R2010b和VS2010编译器(DLL和MEX均使用)进行了测试。
该示例仅仅是将浮点数相加。MEX文件接受矩阵/向量,并循环遍历元素,在每对元素上调用库中的“add()”函数。
Adder.h
#ifndef ADDER_H
#define ADDER_H
#ifdef __cplusplus
extern "C" {
#endif
#ifdef _WIN32
# ifdef BUILDING_DLL
# define DLL_IMPORT_EXPORT __declspec(dllexport)
# else
# define DLL_IMPORT_EXPORT __declspec(dllimport)
# endif
#else
# define DLL_IMPORT_EXPORT
#endif
DLL_IMPORT_EXPORT double add(double x, double y);
#ifdef __cplusplus
}
#endif
#endif
Adder.c
#include "Adder.h"
double add(double x, double y)
{
return x+y;
}
mymexfunction.c
#include "mex.h"
#include "Adder.h"
#define X_IN input[0]
#define Y_IN input[1]
#define Z_OUT output[0]
void mexFunction(int output_size, mxArray *output[], int input_size, const mxArray *input[])
{
double *inX, *inY, *outZ;
mwSize m,n;
int i;
if (input_size != 2) {
mexErrMsgTxt("Two input arguments required.");
}
if (output_size > 1) {
mexErrMsgTxt("Too many output arguments.");
}
m = mxGetM(X_IN);
n = mxGetN(X_IN);
if ( !mxIsDouble(X_IN) || !mxIsDouble(Y_IN) ) {
mexErrMsgTxt("Input arguments must be matrices/vectors of doubles.");
}
if ( mxGetM(Y_IN)!=m || mxGetN(Y_IN)!=n ) {
mexErrMsgTxt("X and Y must be of same size.");
}
Z_OUT = mxCreateDoubleMatrix(m, n, mxREAL);
inX = (double *) mxGetPr(X_IN);
inY = (double *) mxGetPr(Y_IN);
outZ = (double *) mxGetPr(Z_OUT);
for(i=0; i<m*n; ++i) {
outZ[i] = add(inX[i], inY[i]);
}
return;
}
首先,我们需要构建动态库。正如我所提到的,我使用VC++来完成这项工作。对于基于GCC的Unix系统,我认为这一步应该是这样的(如果我错了,请纠正):
gcc -c -DBUILDING_DLL Adder.c -o Adder.o -I.
gcc -shared -o libAdder.so Adder.o -Wl,--out-implib,libAdder.a
然后在MATLAB中,我们编译MEX文件:
>> mex mymexfunction.c -I. -L. -lAdder
(注意:我把所有文件都放在同一个文件夹中,以避免处理路径问题。)
接下来,我们可以在MATLAB中测试该函数:
>> mymexfunction([1 2;3 4], [5 6; 7 8])
ans =
6 8
10 12
使用Sysinternals的
Process Explorer工具,我们可以查看MATLAB进程、MEX函数和自定义动态库加载的DLL。
![sysinternals](https://istack.dev59.com/TC0fX.webp)
如果我们发出命令
clear mex
,那么两个模块都会按预期卸载(这一点可以使用Process Explorer进行验证)。INMEM也证实了这一点,正如
@Praetorian所展示的那样:
clear mex
[~,m] = inmem('-completenames');
any( ismember(m,fullfile(pwd,['mymexfunction.' mexext])) )
最后,如果我们对
mymexfunction.c
进行一些更改:
// add 10 to all results
outZ[i] = add(inX[i], inY[i]) + 10.0
重新编译MEX文件,并在同一个会话中进行测试(无需重新启动)。结果将反映所做的更改,如下所示:
>> mymexfunction([1 2;3 4], [5 6; 7 8])
ans =
16 18
20 22
请尝试在您的Mac/Linux机器上重复上述操作。如果仍然收到旧的总和,则必须是非Windows平台特定的错误,并应向MathWorks报告...否则,我怀疑在您的代码中,可能存在一些未释放的资源导致该模块仍留在内存中?
inmem
应该报告内存中是否有缓存版本!你不是在一个 MATLAB 实例中尝试运行 mex 文件并在另一个实例中编译它吧? - Praetorianinmem
尝试卸载该文件,但无法从操作系统获得确认已实际卸载该文件。您知道第二个库是否打开了其他共享库吗? - Praetorian