Accessing Sdk Dlls From Vb

Post questions and issues with Concept2 PM3 SDK
Post Reply
[old] Chris Brett
Posts: 0
Joined: March 18th, 2006, 10:32 pm

Post by [old] Chris Brett » July 29th, 2005, 2:47 pm

Hi there, I am developing some simple learning tools for use in schools to enable the students to use PM3 data as part of their IT Projects. <br /><br />I have written a simple application for recording PM3 data in C but I need to access the data from Visual Basic. I understand that I need to declare the required Dll functions using alias statements but I am having difficulty passing data to and from the SDK Dlls.<br /><br />I seem to be able to get the tkcmdsetDDI_init function to work using the a declare statement. However when I try to call the tkcmdsetDDI_discover_pm3s function I get the following error message and I realise that this is because of the way that I am passing data to and from the dll when calling the function.<br /><br />Run-time error '49':<br /><br />Bad DLL calling function<br /><br />**********************************************************************************<br />PM3DDI_API ERRCODE_T tkcmdsetDDI_discover_pm3s(INT8_T *product_name, <br /> UINT16_T starting_address,<br /> UINT16_T*num_units);<br />**********************************************************************************<br /><br />Here is my code:<br /><br />Option Explicit<br />' Declare the exported functions from the DLL.<br /><br />Private Declare Function Init Lib "RPPM3DDI.dll" _<br /> Alias "tkcmdsetDDI_init" _<br /> () As Integer<br /><br />Private Declare Function Discover_PM3s Lib "RPPM3DDI.dll" _<br /> Alias "tkcmdsetDDI_discover_pm3s" _<br /> (ByVal Product_Name As String, _<br /> ByVal Start_Address As Integer, _<br /> Num_Units As Integer) As Integer<br /> <br />Dim Error_Message As Integer<br />' Dim Start_Address As Integer<br />Dim Num_Units As Integer<br />Dim Product_Name As String<br />'TKCMDSET_PM3_PRODUCT_NAME2 = "Concept2 Performance Monitor 3 (PM3)"<br /> <br />Private Sub Init_Command_Click()<br /> Text7 = 999<br /> Refresh<br /> Error_Message = Init()<br /> If Error_Message = 0 Then<br /> Text1 = "Init 0k!"<br /> Text7 = Error_Message<br /> Else<br /> Text1 = "Init Error!"<br /> Text7 = Error_Message<br /> End If<br /> Refresh<br />End Sub<br /><br />Private Sub Discover_Command_Click()<br /> ' Start_Address = 0<br /> Error_Message = Discover_PM3s(Product_Name, 0, Num_Units)<br />End Sub<br /><br /><br /><br />I would really appreciate any advice. Thanks a lot for any time you can spare. I apologise in advance if I am making very obvious mistakes.<br /><br />Kind Regards Chris

[old] haboustak

Post by [old] haboustak » July 29th, 2005, 7:29 pm

Chris,<br /><br /><br />Was the error "Bad DLL Calling <i>Convention</i>"? <br /><br />Mostly your Declare looks right to me.<br />ByVal As String will get you a C-String pointer (INT8_T *)<br />ByVal As Integer will get you a two-byte integer value<br /><br />Maybe try adding ByRef to the Num_Units parameter in the tkcmdsetDDI_discover_pm3s() declare. It should be the default argument mode, but it might help.<br /><br />It could be that the functions in the DLL aren't StdCall. I'm not sure on that, it seems like they should be.<br /><br />Also, I don't know if it will matter, but it doesn't look like you're setting the value of Product_Name. Not sure if that would cause the error though.<br /><br />[Edited to Add]<br />I checked the DLL with Microsoft's dumpbin.exe utility and the functions from the DDI DLL do NOT appear to be StdCall. Which agrees with the non-existant __stdcall declaration(s) in the C header file.<br /><br />Somehow, you'll need to get from:<br /><br />PM3DDI_API ERRCODE_T tkcmdsetDDI_discover_pm3s(INT8_T *product_name, UINT16_T starting_address, UINT16_T *num_units)<br /><br />to:<br /><br />PM3DDI_API ERRCODE_T __stdcall tkcmdsetDDI_discover_pm3s(INT8_T *product_name, UINT16_T starting_address, UINT16_T *num_units)<br /><br />You can either write a wrapper DLL in C/C++ or maybe Concept2 can edit the library and re-compile it. Or maybe there is a way to get VB to use __cdecl.<br /><br />

[old] Chris Brett
Posts: 0
Joined: March 18th, 2006, 10:32 pm

Post by [old] Chris Brett » July 30th, 2005, 11:43 am

Thanks a lot for your help haboustak. Chris Rey has given me some advice as well. I will try and implement a wrapper Dll in C.<br /><br />Cheers Chris

[old] ChrisRey

Post by [old] ChrisRey » July 31st, 2005, 2:44 pm

Chris,<br />Rather than have you do either <br />1. a ton(ne) of typing<br />2. write a code generator<br /><br />I've thrown some some odds and sods that may help you at the following link:<br /><br /><a href='http://www.chrisrey.demon.co.uk/c2/' target='_blank'>Odds and sods of source code</a><br /><br />Apologies if they're dense, uncommented, bug ridden or plain wrong but they are free so help yourself. From memory the code hanging from Command4 works occasionally.<br /><br />Good luck.<br /><br />Chris<br /><br />

[old] Chris Brett
Posts: 0
Joined: March 18th, 2006, 10:32 pm

Post by [old] Chris Brett » August 3rd, 2005, 2:52 pm

Thanks again Chris R.<br /><br />I had already got a simple Monitor running after your previous advice (which was incredibly useful!) but this looks really interesting. I will let you know if I manage to come up with anything decent.<br /><br />Much appreciated Chris B.

Post Reply