Пытаясь воспроизвести проблему, я написал минимальный рабочий пример для вашего случая: MEX-файл, который ссылается на динамическую библиотеку и использует одну из ее открытых функций.Я протестировал следующее на 32-битной WinXP с использованием 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;
/* check for proper number of arguments */
if (input_size != 2) {
mexErrMsgTxt("Two input arguments required.");
}
if (output_size > 1) {
mexErrMsgTxt("Too many output arguments.");
}
/* check input argument sizes */
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.");
}
/* Create a matrix for the return argument */
Z_OUT = mxCreateDoubleMatrix(m, n, mxREAL);
// get pointers to data
inX = (double *) mxGetPr(X_IN);
inY = (double *) mxGetPr(Y_IN);
outZ = (double *) mxGetPr(Z_OUT);
// compute and store result
for(i=0; i<m*n; ++i) {
outZ[i] = add(inX[i], inY[i]);
}
return;
}
Сначала мы собираем динамическую библиотеку, как я уже говорил, я использую VC ++ для этой работы.На Unix-системах с GCC я думаю, что этот шаг выглядит следующим образом (поправьте меня, если я ошибаюсь):
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
Используя ProcessИнструмент Explorer от Sysinternals, мы можем просматривать загруженные библиотеки DLL с помощью процесса MATLAB, функции MEX и нашей пользовательской динамической библиотеки:
Если мы введем команду 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 ... В противном случае я подозреваю, что в вашем коде должны быть неосвобожденные ресурсы, вызывающие модульостаться в памяти?