Solved

Interfacing with matlab dlls from Delphi

Posted on 2010-11-18
7
1,803 Views
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)
Output=Input+1;

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:
Input:=1;
MatlabFunc(1,Output,Input);

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.
0
Comment
Question by:PaulC76
  • 3
  • 3
7 Comments
 
LVL 25

Expert Comment

by:epasquier
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

0
 
LVL 21

Expert Comment

by:developmentguru
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.
0
 

Author Comment

by:PaulC76
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
x=2;
x=x+1;

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:

#if defined(ARRAY_ACCESS_INLINING) && !defined(MATLAB_COMPILER_GENERATED_CODE)
/*
 * 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;
};
#endif /* ARRAY_ACCESS_INLINING */

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.
0
Free Tool: Path Explorer

An intuitive utility to help find the CSS path to UI elements on a webpage. These paths are used frequently in a variety of front-end development and QA automation tasks.

One of a set of tools we're offering as a way of saying thank you for being a part of the community.

 

Author Comment

by:PaulC76
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:

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

Open in new window

Implementation:
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.
0
 
LVL 25

Expert Comment

by:epasquier
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

0
 

Author Comment

by:PaulC76
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.
0
 
LVL 25

Accepted Solution

by:
epasquier earned 250 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
0

Featured Post

Announcing the Most Valuable Experts of 2016

MVEs are more concerned with the satisfaction of those they help than with the considerable points they can earn. They are the types of people you feel privileged to call colleagues. Join us in honoring this amazing group of Experts.

Question has a verified solution.

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

Navigation is an important part of web design from a usability perspective. But it is often a pain when it comes to a developer’s perspective. By navigation, it often means menuing. This is less theory and more practical of how to get a specific gro…
Having just graduated from college and entered the workforce, I don’t find myself always using the tools and programs I grew accustomed to over the past four years. However, there is one program I continually find myself reverting back to…R.   So …
This theoretical tutorial explains exceptions, reasons for exceptions, different categories of exception and exception hierarchy.
The viewer will learn how to user default arguments when defining functions. This method of defining functions will be contrasted with the non-default-argument of defining functions.

828 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