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

15 views (last 30 days)
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.
Thanks!
  2 Comments
Ryan Livingston
Ryan Livingston on 5 Feb 2013
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:
Alexei Halpin
Alexei Halpin on 5 Feb 2013
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

Sign in to comment.

Accepted Answer

Philip Borghesani
Philip Borghesani on 5 Feb 2013
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
Alexei Halpin
Alexei Halpin on 5 Feb 2013
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! http://www.mathworks.com/matlabcentral/answers/25697 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.

Sign in to comment.

More Answers (0)

Products

Community Treasure Hunt

Find the treasures in MATLAB Central and discover how the community can help you!

Start Hunting!