## MATLAB Compiler Problem (?)

### MATLAB Compiler Problem (?)

Hi there,

I have tried to generate some stand-allone dll that are supposed to be
accessed from a Visual Basic application in MATLAB 6.1 (R12.1) using the
MATLAB Compiler 2.3. Solution number 28621 in the MATH-Works Solution
Database shows a nice way to solve this problem but it is just dealing with
scalars. I have to transfer arrays.

To show where my problem is I have created a very simple function that is
located in CDatFunc.m and just shifts the contains of one array to another
one. The way how this is done has to do with the original tasks, which
should not to be concerned here.

function C = CDatFunc(A)

NoR = size(A,1);                            %   number of rows in array A
NoC = size(A,2);                            %   number of collumns in array
A

C = [];                                             %   declare array C

for i=1:NoR                                     %   for all rows
for j=1:NoC                                 %   for all collums
D(j) = A(i,j);                            %   write array element
A(i,j) into help vector
end
C = [C; D(:)'];                             %   add completed help
vector to array C
end

C(1,1) = size(C,1);                         %   write length of array C into
the first element

return;

CDatFunc.m is then compiled into C code that can be included in a C shared
library by using the MATLAB compiler:

mcc -W lib:CDatLib -L C -t CDatFunc.m

This generates the following files: CDatFunc.c, CDatFunc.h, CDatLib.c,
CDatLib.h, CDatLib.mlib, CDatLib.exports

Now a wrapper file is created in Visual C/C++ looking as follows:

#include "CDatLib.h"
#include "matlab.h"
#include "matrix.h"

// prototype for mlfCDatFunc
extern mxArray *mlfCDatFunc(mxArray* A);

void _stdcall CDatFunc(int ELen, int EWidth, double* ADat, double* CDat)
{
int i,j,k;                                        // declaration of
variables

double *EHelp;                            // declaration of pointers
mxArray *CDat_ptr = NULL;

// create mxArrays for input into mlfCDatFunc

// initialize library
CDatLibInitialize();

// call MATLAB function CDatFunc

// the return value from mlfCDatFunc is a pointer to a mxArray,
// thus, the data must be extracted from there
EHelp = mxGetPr(CDat_ptr);

k = 0;
for (i=0; i<ELen; i++)
for(j=0; j<EWidth; j++)
{
CDat[k] = EHelp[k];
k++;
}

// free memory used for the mxArrays
mxDestroyArray(CDat_ptr);

Quote:}

Compiling and linking this with the Visual C/C++ compiler generates a
dynamic link library CDatFunc.dll . I call this dll from a small Visual
Basic program that I created just for testing purpose. The function in the
dll has to be declared as follows:

Private Declare Sub CDatFunc Lib "CDatFunc.dll" (ByVal EFileLen As Integer,
ByVal EFileWidth As Integer, EFile As Double, EDat As Double)

According to Visual Basic conventions the arrays EFile and EDat are
transfered by their pointers because they are not declared ByVal. Thus, in
the call of the function CDatFunc only the very first elements of the arrays
are transferred. The VB subprogram that calls the dll is as follows:

Private Sub CDat_Button_Click()

Dim FileLen, FileWidth As Integer
ReDim mdFFile(UBound(mdEFile, 1), UBound(mdEFile, 2))

FileLen = UBound(mdEFile, 1)
FileWidth = UBound(mdEFile, 2)

Call CDatFunc(FileLen, FileWidth, mdEFile(0, 0), mdFFile(0, 0))

Call WriteArrayToList(mdFFile, List3)

End Sub

The function WriteArrayToList visualizes the contains of the returned array
mdFFile in the list List3. For test purposes I uses a very simple array for
mdEFile --> ADat --> A :

1    2    3    4    5
6    7    8    9    10
11    12    13    14    15
16    17    18    19    20
21    22    23    24    25
26    27    28    29    30
31    32    33    34    35
36    37    38    39    40
41    42    43    44    45
46    47    48    49    50

Normally one would expect, that the array C --> CDat --> mdFFile contains
exactly the same data than A except of the first element, which now contains
the length of the array C, which shoud be 10. But what is really returned
is:

9    3    4    5    0
7    8    9    10    0
12    13    14    15    0
17    18    19    20    0
22    23    24    25    0
27    28    29    30    0
32    33    34    0    0
37    38    39    0    0
42    43    44    0    0
47    48    49    0    0

If I change the line  EHelp = mxGetPr(CDat_ptr);  in the C wrapper file into
EHelp = mxGetPr(ADat_ptr);  the returned array is, as expected, exactly
identical to the input array. The problem is obviously not located in the C
code. If I call the MATLAB function as m code from a short MATLAB test
program it also works fine and returns the array as expected.

Thus, something has to be wrong with the compilation or maybe with the
compiler options that I chose. Does anybody have an idea what might be wrong
there?

Thanks in advance for the help.
Regards.

Wolfgang

This is my first time using the MATLAB compiler.  I apologize in
advance if my questions seem amateurish. I would greatly appreciate
any advice that you can offer me.  I am trying to convert
a simple m function svm into a c program on a lynx platform using
version 2.1 (R12) of the MATLAB compiler. The comand

mcc -t -L C svm

produced the necessary .c and .h files. When I tried to compile
these files using gcc, I decided to err on the side of caution
and to link in all the following library files

fexport.map libeng.so libmat.so libmatlb.so libmi.so libmwcl.so
libmx.so libut.so mexFunction.map mexLibrary.map version4.o.
libmmfile.so

However, gcc generated a number of "undefined reference to"
errors like

/tmp/ccZYwMGU.o: In function `TerminateModule_svm':
/tmp/ccZYwMGU.o(.text+0x2082): undefined reference to `mxDestroyArray'
/tmp/ccZYwMGU.o(.text+0x208d): undefined reference to `mxDestroyArray'
/tmp/ccZYwMGU.o(.text+0x2098): undefined reference to `mxDestroyArray'
/tmp/ccZYwMGU.o(.text+0x20a3): undefined reference to `mxDestroyArray'
/tmp/ccZYwMGU.o(.text+0x20ae): undefined reference to `mxDestroyArray'
/tmp/ccZYwMGU.o: In function `mlfSvm':
/tmp/ccZYwMGU.o(.text+0x2135): undefined reference to
?`mlfEnterNewContext'
/tmp/ccZYwMGU.o(.text+0x2145): undefined reference to
?`mlfRestorePreviousContext'

All the "undefined reference to" errors involved constructor
and deconstructor like functions starting with prefixes like
mx, mcl, and mlf. What library(s) am I failing to link in?
Whatever these libraries are, they are not in the extern/lib
directory.