Go Premium for a chance to win a PS4. Enter to Win


Interfacing with matlab dlls from Delphi

Posted on 2010-11-18
Medium Priority
Last Modified: 2016-03-02
I am trying to use functions written in Matlab from Delphi. The test function is very simple, it just adds one to an input variable as follows:

function [Output] = AddOne(Input)

I've managed to compile it ok and access the dll from delphi, but I get an access violation at the line where I try to use the function.

l define the function in Delphi as follows:

In the interface:

function MatlabFunc(NRetValues: Integer;var Output: Variant;var Input: Variant): Variant; cdecl;

In the implementation:

function MatlabFunc(NRetValues: Integer;var Output: Variant;var Input: Variant): Variant; cdecl; external 'AddOne.dll' name '_mlxAddOne';

Then call it:

I've installed all the relevant matlab runtime libraries and everything seems to work ok, I think it's just a matter of figuring out the correct calling convention. Or do I have to use mclInitializeApplication or something? It does appear from web searches that people have had similar problems and that some people have managed to solve it, but no-one explains quite how.
Question by:PaulC76
  • 3
  • 3
LVL 25

Expert Comment

ID: 34169621
the calling convention is most probably stdcall;

for the parameters types translation, it would be useful to have C headers (.H files), probably generated when you compile your function.
I doubt very much that those parameters are Variant.

I think also that you have to call the initialize function for the lib, and call the Terminate when done.

something like
function MatlabFunc(NRetValues: Integer;var Output: Variant;var Input: Variant): Variant; stdcall; external 'AddOne.dll' name '_mlxAddOne';

procedure AddOneInitialize; stdcall; external 'AddOne.dll'  name '_MatlabFuncInitialize';

procedure AddOneTerminate; stdcall; external 'AddOne.dll'  name '_MatlabFuncInitialize';

Open in new window

LVL 21

Expert Comment

ID: 34170566
The MatLab compiler generates both the dll and a header filer.  Can you post the header file?  Many experts are good at translating a C / C++ header into the correct Delphi calling conventions.  From what I have been able to tell MatLab generates CDecl calling conventions.

Author Comment

ID: 34182881
I have since tried calling the mclInitializeApplication first and then using a function which has no parameters and still get the same error. In the interface I now have:
function InitialiseMatlab(): Boolean; cdecl;
function NoParam(): Boolean; cdecl;

Open in new window

and in the implementation:

  function InitialiseMatlab(Options: Variant; Count: Word): Boolean; cdecl; external 'NoParam.dll' name '_NoParamInitialize';
function NoParam(): Boolean; cdecl; external 'NoParam.dll' name '_mlfNoParam';

Open in new window

The function in matlab is as follows:

function NoParam

Open in new window

The InitialiseMatlab function executes ok, but returns false. An access violation then occurs when NoParam tries to execute. Matlab generates a header file and c code, which are attached.

 NoParam.h NoParam.c

The header file has the relevant interfaces to the function:

extern LIB_NoParam_C_API 
bool MW_CALL_CONV NoParamInitializeWithHandlers(mclOutputHandlerFcn error_handler,
                                                mclOutputHandlerFcn print_handler);

extern LIB_NoParam_C_API 
bool MW_CALL_CONV NoParamInitialize(void);

extern LIB_NoParam_C_API 
void MW_CALL_CONV NoParamTerminate(void);

extern LIB_NoParam_C_API 
bool MW_CALL_CONV mlxNoParam(int nlhs, mxArray *plhs[],
                             int nrhs, mxArray *prhs[]);

extern LIB_NoParam_C_API bool MW_CALL_CONV mlfNoParam();

Open in new window

Any parameters if needed are mxArray types, which is partially defined in the header file Matrix.h as follows:

 * This modified version of the mxArray structure is needed to support
 * the ARRAY_ACCESS_INLINING macros.  NOTE: The elements in this structure
 * should not be accessed directly.  Inlined MEX-files are NOT guaranteed
 * to be portable from one release of MATLAB to another.

struct mxArray_tag {
    void    *reserved;
    int      reserved1[2];
    void    *reserved2;
    int      number_of_dims;
    unsigned int reserved3;
    struct {
        unsigned int    scalar_flag : 1;
	unsigned int	flag1 : 1; 
        unsigned int    flag2 : 1;
        unsigned int    flag3 : 1;
        unsigned int    flag4 : 1;
        unsigned int    flag5 : 1;
        unsigned int    flag6 : 1;
        unsigned int    flag7 : 1;
        unsigned int    private_data_flag : 1;
        unsigned int    flag8 : 1;
        unsigned int    flag9 : 1;
        unsigned int    flag10 : 1;
        unsigned int    flag11 : 4;
        unsigned int    flag12 : 8;
        unsigned int    flag13 : 8;
    }   flags;
    unsigned int reserved4[2];
    union {
        struct {
            void  *pdata;
            void  *pimag_data;
            void  *reserved5;
            int    reserved6[3];
        }   number_array;
    }   data;

Open in new window

Converting that to Delphi is the point where I give up I think, I've spent more time than I have for this already.
Concerto's Cloud Advisory Services

Want to avoid the missteps to gaining all the benefits of the cloud? Learn more about the different assessment options from our Cloud Advisory team.


Author Comment

ID: 34186868
My previous comment was a bit confusing. In the example I posted I didn't use the global mclInitializeApplication, but the local initialisation function NoParamInitialize. I have since tried with mclInitializeApplication as follows:

TCharPointer = ^Char;
TCharPointerPointer =^TCharPointer;
function InitialiseMatlab(const Options:  TCharPointerPointer; Count: Word): Boolean; cdecl; 

Open in new window

function InitialiseMatlab(const Options:  TCharPointerPointer; Count: Word): Boolean; cdecl; external 'mclmcrrt76.dll' name 'mclInitializeApplication';

Open in new window

The C header as given in the Matlab help is:
bool mclInitializeApplication(const char **options, int count);

Open in new window

In the example in the Matlab help "mclInitializeApplication(NULL,0);" is given as an example of usage, I've tried "InitialiseMatlab(nil,0);" and passing pointers to pointers to #0, but always get a return value of False.
LVL 25

Expert Comment

ID: 34187031
why do you have thie ?
function InitialiseMatlab(Options: Variant; Count: Word): Boolean; cdecl; external 'NoParam.dll' name '_NoParamInitialize';

shouldn't you call this :

function InitialiseMatlab: Boolean; cdecl; external 'NoParam.dll' name '_NoParamInitialize';

if InitialiseMatlab Then ShowMessage('Good') Else Raise Exception.Create('Could not initialize MathLab Dll');

Open in new window

then : TCharPointer = ^Char;
that type already exists, that's PChar. But I recommend using PAnsiChar, because if you have Delphi >=2009 then Char = WideChar (unicode), so for C dll you have to use ANSIChar explicitly. And Count is not Word (2 bytes) but Integer (or Cardinal)

function InitialiseMatlabOptions(const Options:  ^PANSIChar; Count: Integer ): Boolean; cdecl; external 'NoParam.dll' name 'mclInitializeApplication';

Open in new window


Author Comment

ID: 34187191
Very sorry, the function was InitialiseMatlab was defined as you have it in your first code segment, it was copied from code I was in the middle of changing to use the mclInitialize function instead of NoParamInitialize. I also had originally defined Count as an Integer, but changed it to Word as part of my desperate and lazy trial and error approach. Also Delphi doesn't allow you to define pointers as function parameters in the function prototype (e.g.^PANSIChar), you have to define them as types first.

Anyway, I've since done as you kindly suggested and it still returns false. Thanks very much for your help with this, but please don't waste any more time on it, as I'm not able to spend too long on it myself now and I don't want to trouble anyone else with it too much.
LVL 25

Accepted Solution

epasquier earned 1000 total points
ID: 34187324
Ok, I'm about sure that those Delphi declarations are good, compared to the C headers. So, since it returns False, and don't raise exceptions of any kind, we have to suppose that the call is working, but for a reason it cannot initialize MathLab... Maybe some wrong parameter in you MathLab environment

Featured Post

Hire Technology Freelancers with Gigs

Work with freelancers specializing in everything from database administration to programming, who have proven themselves as experts in their field. Hire the best, collaborate easily, pay securely, and get projects done right.

Question has a verified solution.

If you are experiencing a similar issue, please ask a related question

Have you ever had your Delphi form/application just hanging while waiting for data to load? This is the article to read if you want to learn some things about adding threads for data loading in the background. First, I'll setup a general applica…
Q&A with Course Creator, Mark Lassoff, on the importance of HTML5 in the career of a modern-day developer.
This tutorial explains how to use the VisualVM tool for the Java platform application. This video goes into detail on the Threads, Sampler, and Profiler tabs.
The viewer will learn how to use the return statement in functions in C++. The video will also teach the user how to pass data to a function and have the function return data back for further processing.
Suggested Courses

879 members asked questions and received personalized solutions in the past 7 days.

Join the community of 500,000 technology professionals and ask your questions.

Join & Ask a Question