MATLAB Answers

Alexei Halpin

Properly passing pointer arguments to .dll functions using loadlibrary and calllib

Hello, I am loading the .dll corresponding to a new piece equipment. Having never really worked with the calllib environment before I'm running into some problems. Calling functions from the .dll using calllib works for functions which do not possess any arguments (thankfully!), but I'm running into problems for those which require pointer arguments. I suspect this is an issue of improperly casting the values for the pointers.. But I've had no luck getting this to work without errors.

For example, I have two functions (to set a gain parameter) which according to the manufacturer docs has the following form

SetGain(INT ngain)

GetGain(INT* pgain)

When I load the library into Matlab R2007b and produce a detailed list of functions, I see these have the following form:

[lib.pointer, voidPtr] SetGain(voidPtr)

[lib.pointer, voidPtr] GetGain(voidPtr)

From there, in order to test that I've indeed set that parameter to an appropriate value (say 2), I write the following:

g = libpointer('voidPtr',uint8(2))

[status, gain] = calllib('lib', 'SetGain', g);

t = libpointer('voidPtr');

[status,t] = calllib('lib', 'GetGain', t);

Following the second line of code, I usually get a hardware error for invalid parameter, so clearly the input is not of the right type, but more alarmingly when I attempt to read out the Gain (which by default should be 1, even if the preceding command failed), calling the GetGain function returns an empty array. I'm certain the answer is staring me in the face. What am I doing wrong? I am defining the variable to be the correct pointer types as far as I can tell, and the first one is initialized to a realistic value.



I would guess that INT is a typedef in some header file. Can you look through the header files provided by the manufacturer and see what that type actually is? Then, I would recommend using a compatible pointer type:

Also, it is usually necessary to set the type of a libpointer before reading its value as an output argument:

Thanks for your input Ryan. Indeed, I checked the header file and the argument is indeed INT for the SetGain and INT* for the GetGain. That's why I'm a bit confused as to why the arguments show up as voidPtr in Matlab after loading the library, instead of int types or int32Ptr for example. I've tried defining the libpointer type for the second function (again as a voidPtr) but it always just returns an empty array with no type. I've plugged away trying different types for libpointer. I was mostly concerned that I was going about this the completely wrong way.

Should I simply ignore the fact that Matlab is asking for voidPtr arguments and just set the pointer types based on the arguments shown in the header files? eg:

g = libpointer('int32',2); %On the basis of the header file showing an INT argument

t = libpointer('int32Ptr'); %Since the second function takes an INT* arg


1 Answer

Answer by Philip Borghesani on 5 Feb 2013
 Accepted answer

Your library is not correctly loaded, trying to call the functions in without fixing the load will only lead to frustration with pointers. I expect there were a large number of warnings from your call to loadlibrary. Ryan is on the correct track you need to have a header file that is compilable without prior includes for loadlibrary to work correctly. For these functions you need a definition of INT.

There are quite a few ways to solve the problem two options are: You can use the "mfilename" name option to loadlibrary and then fix the function definitions in the genereated header file. Or you can modify the header file or create a new one that has the correct #include statements in it.

I suggest fixing or creating a fixed header file. Look and a c example program for the library you are using and add any #include statements from it to the beginning of the header you are using with loadlibrary.

If you wish to create a new header file add the needed includes then a #include for the header you are trying to load. When you call loadlibrary use the addheader option and specify the original header name.

  1 Comment

Hi Philip.

Funny, right before you posted your answer I stumbled onto this question from last year about a similar problem which you helped answer! So far, by adding #include "windows.h" to the header all of the LHS and RHS fields are now correct after reloading the library. So I think we are on the right track. Thanks for your help, we will probably use a prototype function as well now that I understand its role better.

Discover MakerZone

MATLAB and Simulink resources for Arduino, LEGO, and Raspberry Pi

Learn more

Discover what MATLAB® can do for your career.

Opportunities for recent engineering grads.

Apply Today

MATLAB Academy

New to MATLAB?

Learn MATLAB today!