Trying to reproduce the problem, I've written a minimum working example for your case: a MEX file that links against a dynamic library and use use one of its exposed functions. I've tested the following on WinXP 32-bit using MATLAB R2010b with VS2010 as compiler (for both the DLL and MEX).
The example simply adds floating-point numbers. The MEX file accepts matrices/vectors and loops over the elements calling the add()
function from the library on each pair.
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;
}
First we build the dynamic library, as I mentioned I am using VC++ for the job. On Unix-based systems with GCC, I think this step goes like (correct me if I am wrong):
gcc -c -DBUILDING_DLL Adder.c -o Adder.o -I.
gcc -shared -o libAdder.so Adder.o -Wl,--out-implib,libAdder.a
then in MATLAB, we compile the MEX file:
>> mex mymexfunction.c -I. -L. -lAdder
(Note: I put everything in the same folder to avoid dealing with path issues.)
Next, we can test the function in MATLAB:
>> mymexfunction([1 2;3 4], [5 6; 7 8])
ans =
6 8
10 12
Using the Process Explorer tool from Sysinternals, we can view the loaded DLLs by the MATLAB process, the MEX function and our custom dynamic library:
If we issue the command clear mex
then both modules are unloaded as expected (which is verified using Process Explorer). This is also confirmed by INMEM as @Praetorian showed:
clear mex
[~,m] = inmem('-completenames');
any( ismember(m,fullfile(pwd,['mymexfunction.' mexext])) )
Finally if we make some changes to mymexfunction.c
:
// add 10 to all results
outZ[i] = add(inX[i], inY[i]) + 10.0;
recompile the MEX, and test it again (all in the same session, no restart). The result will reflect the changes made as you can see:
>> mymexfunction([1 2;3 4], [5 6; 7 8])
ans =
16 18
20 22
Please try to repeat the above on your Mac/Linux machine. If you still receive the old sums, then it must be a bug specific to non-Windows platforms, and should be reported to MathWorks... Otherwise I suspect that in your code, there must be some un-released resources causing the module to remain in memory?