08-23-2017 03:33 PM
I am starting to work with some servos from http://www.jrkerr.com/software.html and I am having problems working with multiple servos. I have been able to get their LabVIEW drivers to work with 1 servo, but not the 5 servos I will need to control. I am currently working to modifying the drivers so they can control with multiple servos. So I am brushing up on my hex programming while doing this.
But while I am working on that I was wondering if it might be easier to use the DLL. I have looked around and it seems the DLL import wizard can have issues with C++ DLL's. I have not programmed in C++, but I am guessing that the first problem is that the NMCLIB04.DLL does not have an h file. So I am assuming that the DLL is calling the sub routines that do have h files and the import wizard does not like that.
So I thought I would ask for some help or pointed in the right direction to get the DLL working, while I continue to search for answers on how to make it work.
Bryan
Currently using LabVIEW 2011 on this project
Solved! Go to Solution.
08-24-2017 02:00 AM - edited 08-24-2017 02:13 AM
The DLL is not calling soubroutines that have header files, but instead consists of the subroutines that have header files. And it exports most of those functions too.
Basically the Servo... functions are implemented using the picservo.cpp file and the exported functions are defined in picservo.h.
The Nmc... functions are implemented in nmccom.cpp and the exported functions are defined in nmccom.h.
And the DLL exports the standard C functions despite being implemented in C++. So for the LabVIEW import library Wizard they shouldn't really form any problem. Just refrain from importing the XxxNewMod() functions. They are used internally in the library when you connect to the device but should never be executed from any caller. In fact they should never have been exported from the DLL.
Not a very friendly setup for the Import Library Wizard, but still doable. Easiest would be to create a seperate VI library for each header file in there with the Import Library Wizard.
08-24-2017 11:28 AM
@rolfk wrote:
The DLL is not calling soubroutines that have header files, but instead consists of the subroutines that have header files. And it exports most of those functions too.
Basically the Servo... functions are implemented using the picservo.cpp file and the exported functions are defined in picservo.h.
The Nmc... functions are implemented in nmccom.cpp and the exported functions are defined in nmccom.h.
And the DLL exports the standard C functions despite being implemented in C++. So for the LabVIEW import library Wizard they shouldn't really form any problem. Just refrain from importing the XxxNewMod() functions. They are used internally in the library when you connect to the device but should never be executed from any caller. In fact they should never have been exported from the DLL.
Not a very friendly setup for the Import Library Wizard, but still doable. Easiest would be to create a seperate VI library for each header file in there with the Import Library Wizard.
I tried using the import library wizard using NMCLIB04.dll and the picservo.h and only one function (ServoNewMod()) can be imported. If for example I click on ServoStopMotor () I get the following error:
extern "C" WINAPI __declspec(dllexport) BOOL ServoStopMotor(byte addr, byte mode);
Undefined symbols can prevent the wizard from recognizing functions and parameters. To correct this problem, check the header file to determine if you must add preprocessor definitions. Click the Back button to return to the previous page of the wizard to add a preprocessor definitionsl (for example, "NIAPI_stdcall = __stdcall" or "NIAPIDefined = 1").
So I tried adding NIAPI_stdcall = ServoStopMotor to the preprocessor definitions, but it did not enable the ServoStopMotor item to be wrapped. I also tried a few variations like NIAPI_stdcall = WINAPI __declspec(dllexport) BOOL ServoStopMotor(byte addr, byte mode).
So which part of the picservo.h file is supposed to be entered into the preprocessor definitions? I am assuming that I will need to add every function to the preprocessor definitions that I want to use?
08-24-2017 02:16 PM - edited 08-24-2017 02:24 PM
@_Bryan wrote:
@rolfk wrote:
The DLL is not calling soubroutines that have header files, but instead consists of the subroutines that have header files. And it exports most of those functions too.
Basically the Servo... functions are implemented using the picservo.cpp file and the exported functions are defined in picservo.h.
The Nmc... functions are implemented in nmccom.cpp and the exported functions are defined in nmccom.h.
And the DLL exports the standard C functions despite being implemented in C++. So for the LabVIEW import library Wizard they shouldn't really form any problem. Just refrain from importing the XxxNewMod() functions. They are used internally in the library when you connect to the device but should never be executed from any caller. In fact they should never have been exported from the DLL.
Not a very friendly setup for the Import Library Wizard, but still doable. Easiest would be to create a seperate VI library for each header file in there with the Import Library Wizard.
I tried using the import library wizard using NMCLIB04.dll and the picservo.h and only one function (ServoNewMod()) can be imported. If for example I click on ServoStopMotor () I get the following error:
extern "C" WINAPI __declspec(dllexport) BOOL ServoStopMotor(byte addr, byte mode);
Undefined symbols can prevent the wizard from recognizing functions and parameters. To correct this problem, check the header file to determine if you must add preprocessor definitions. Click the Back button to return to the previous page of the wizard to add a preprocessor definitionsl (for example, "NIAPI_stdcall = __stdcall" or "NIAPIDefined = 1").
So I tried adding NIAPI_stdcall = ServoStopMotor to the preprocessor definitions, but it did not enable the ServoStopMotor item to be wrapped. I also tried a few variations like NIAPI_stdcall = WINAPI __declspec(dllexport) BOOL ServoStopMotor(byte addr, byte mode).
This is just an example, not the actual error that caused the recognition of the function to fail!
So which part of the picservo.h file is supposed to be entered into the preprocessor definitions? I am assuming that I will need to add every function to the preprocessor definitions that I want to use?
Depending on the LabVIEW version you may need to add to the Preprocessor Definitions something like:
byte=char; BOOL=long; WINAPI=__stdcall
However the problem in this case is the function declaration putting the return type behind the function attributes. Change all the function declarations in the header from:
extern "C" WINAPI __declspec(dllexport) byte ServoGetAD(byte addr);
to:
extern "C" byte WINAPI __declspec(dllexport) ServoGetAD(byte addr);
and it should recognize most of the functions now (may had to define some extra types).
The really important part is that WINAPI stands after the return type. Most Visual C compilers impose that limit too. So this works also:
extern "C" __declspec(dllexport) byte WINAPI ServoGetAD(byte addr);
The C standard doesn't really say anything about the __stdcall and __declspec() declarators in any way, they are pure Microsoft extensions. It therefore also doesn't say if they should be before or after the return type declarator. Technically speaking the __stdcall and __declspec() declerators are attributes for the function so it makes sense to put them closer to the function name and prepend the return type to the whole.
08-24-2017 04:31 PM
Thank you very much for the help!
Changing the function declarations in the file did the trick and everything seems to have imported with no issues. It should be much easier to program using the DLL instead of rewriting everything using hex commands.
Thanks again,
Bryan