Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Passing pointer argument in MATLAB to a C-DLL function foo(char**)

I am writing a C-DLL to be called from MATLAB. Is it possible to call a function with const char ** parameter? e.g.

void myGetVersion( const char ** );

The C code would be:

const char *version=0;
myGetVersion( &version );

What would be corresponding MATLAB-Code (if it is possible at all)?

Thank you very much!

P.S.: I think this is the help page, but I couldn't find my case :-(

like image 647
Valentin H Avatar asked Sep 16 '11 13:09

Valentin H


People also ask

How do you pass a pointer to a function in MATLAB?

Pass Pointer of Type double Construct a pointer, Xptr , to the input argument, X . X = 13.3; Xptr = libpointer('doublePtr',X); Verify the contents of Xptr . Call the function and check the results.

Can you use pointers in MATLAB?

Pointer Arguments in C Functions Although MATLAB® does not support passing by reference, you can create a MATLAB argument, called a lib. pointer object, that is compatible with a C pointer. This object is an instance of the MATLAB lib. pointer class.


2 Answers

The answer is to build a pointer to a c-string using the LIBPOINTER function as @JonasHeidelberg suggested. Let me expand his solution with a working example..

First lets build a simple DLL:

version.h

#ifndef VERSION_H
#define VERSION_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 void myGetVersion(char**str);

#ifdef __cplusplus
}
#endif

#endif

version.c

#include "version.h"
#include <string.h>

DLL_IMPORT_EXPORT void myGetVersion(char **str)
{
    *str = strdup("1.0.0");
}

You can use your preferred compiler to build the DLL library (Visual Studio, MinGW GCC, ..). I am using MinGW to compile the above, here is the makefile I am using:

Makefile

CC = gcc

all: main

libversion.dll: version.c
    $(CC) -DBUILDING_DLL version.c -I. -shared -o libversion.dll

main: libversion.dll main.c
    $(CC) main.c -o main -L. -lversion

clean:
    rm -rf *.o *.dll *.exe

Before we move to MATLAB, lets test the library with a C program:

main.c

#include <stdio.h>
#include <stdlib.h>
#include "version.h"

int main()
{
    char *str = NULL;
    myGetVersion(&str);
    printf("%s\n", str);
    free(str);

    return 0;
}

Now that all is working, here is how to use this library from MATLAB:

testDLL.m

%# load DLL and check exported functions
loadlibrary libversion.dll version.h
assert( libisloaded('libversion') )
libfunctions libversion -full

%# pass c-string by reference
pstr = libpointer('stringPtrPtr',{''}); %# we use a cellarray of strings
get(pstr)
calllib('libversion','myGetVersion',pstr)
dllVersion = pstr.Value{1}

%# unload DLL
unloadlibrary libversion

The output with the string returned:

Functions in library libversion:
stringPtrPtr myGetVersion(stringPtrPtr)

       Value: {''}
    DataType: 'stringPtrPtr'

dllVersion =
1.0.0
like image 131
Amro Avatar answered Oct 02 '22 22:10

Amro


Looking at Working with pointers, section Passing an Array of Strings in the MATLAB documentation (linked from the help page you linked in your question), it seems you need to construct a libpointer object in MATLAB, something like

version = libpointer('stringPtrPtr',{''}); %# corrected according to Amro's comment
calllib('yourCdll', 'myGetVersion', version)

(I don't have a DLL to test this with right now, and I'm not very firm on C pointers, so no guarantee... hope this is a step in the right direction)

like image 40
Jonas Heidelberg Avatar answered Sep 29 '22 22:09

Jonas Heidelberg