Using Propellent.DLL with VS2010?
ozpropdev
Posts: 2,793
Hi Guys,
I am having trouble trying to interface the Propellent.DLL into my Visual Studio application.
I am using Visual Basic with Vista OS. I can get some of the simple function calls to work
such as GetLibraryVersion and GetResetSignal but get errors trying to use InitPropellent.
Using external functions in a DLL is new to me and I am a bit confused on the PChar data type. Has anyone used Propellent.DLL with Visual Basic?
Thanks
I am having trouble trying to interface the Propellent.DLL into my Visual Studio application.
I am using Visual Basic with Vista OS. I can get some of the simple function calls to work
such as GetLibraryVersion and GetResetSignal but get errors trying to use InitPropellent.
Using external functions in a DLL is new to me and I am a bit confused on the PChar data type. Has anyone used Propellent.DLL with Visual Basic?
Thanks
Comments
I'm not very familiar with C++ so I can't compare with VB.
My code looks like this
Declare Sub InitPropellent Lib "c:\propellent.dll" (ByVal Winhandle, ByVal storeprefs, ByVal regpath)
Declare Function GetLibraryVersion Lib "c:\propellent.dll" () As Integer
Declare Function GetSerialSearchMethod Lib "c:\propellent.dll" () As Integer
Declare Function GetResetSignal Lib "c:\propellent.dll" () As Byte
Private Sub Button1_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button1.Click
Dim ver As Integer
Dim ssm As Integer
Dim rs As Byte
Dim hd As Integer = Me.Handle
Dim sp As Boolean = False
Dim rp As Integer = 0
InitPropellent(hd, sp, rp) '<-- Fails here with -> "External component has thrown an exception."
ver = GetLibraryVersion() '<-- This works!
ssm = GetSerialSearchMethod
rs = GetResetSignal
Dim msg As String
msg = "Library version =" + ver.ToString + vbCrLf
msg &= "Serial search method =" + ssm.ToString + vbCrLf
msg &= "Reset signal =" + rs.ToString
MsgBox(msg)
End Sub
If I remove the InitPropellent line the code after it works OK.
There must be something simple i'm missing but my knowledge is somewhat
limited in this area.
Regards
Jeff T.
Edit.....I noticed an error in the assigned buttons that I posted.....in my routines buttons 1 2 and 3 should be reserved for the download process , load Ram and run , load EEPROM and stop and load EEPROM and run. Just rearrange the buttons for each sub
I have tried your code and i'm still not getting past the "Init" stage.
VS2010 is spitting out the following error for this line of code.
Init(hwnd, False, y) '<- "PInvokeStackImbalance was detected"
I also had to add the following code before the Class declaration to accept your code.
Imports System
Imports System.Runtime.InteropServices
Any ideas?
Regards Brian
Bill
Do you have the Propellent dll in the System32 directory and I see the variable y in there , I never had the y variable is that something you altered to suit? Did you rearrange the button assignments ( 1 2 and 3 reserved for download)
Jeff T.
Jeff, the Y was a typo but the real code was correct with a X. Propellent is in the System32
folder as well.
All button names match with your code.
Bill, thanks for your VS2008 code sample.
Some crazy things are happening with your code Guys.
I loaded Bill's code into VS2010 and it converted it and "Init" works.
But if i create a new form and copy Jeff's code, I get the same error as before.
Looking at the code I can't see any real difference between them?
I even tried it on another machine running XP instead of Vista with the same results.
In the Propellent V1.2 documentation for the "InitPropellent" routine it states that
the PChar data type is 32 bits while both your declerations use Long which in VS2010 is
64 bits?
Dazed and confused
Brian
Bill's VS2008 code that seemed to work on its own was pasted into my application
and it is now spitting out the same error.
"PInvokeStackImbalance was detected"
I also noticed that the "glv" function has been declared with LONG yet the Propellent
documentation shows a BYTE is returned. On the version that worked I changed this
to BYTE and it returns "18" instead of a large number.
It's a mystery....
Maybe I need to change my brand of coffee?
Regards Brian
I seem to have stumbled on a fix for my error problem.
The problem seems to be related to any sub/function that passes variables to
the Propellent.dll.
Based on the code you guys sent me I duplicated the <dllimport>
command for each of my declarations that pass varaibles. For each of these I also set
the CallingConvention to CDECL mode instead of STDCALL.
For the string passing I also used ANSI mode rather than UNI mode and that fixed
my string passing issues as well
Sample code
<DllImport("Propellent", EntryPoint:="InitPropellent", CallingConvention:=CallingConvention.Cdecl)>
Public Shared Sub start(ByVal hw As IntPtr, ByVal sp As Boolean, ByVal rp As IntPtr)
End Sub
Private Declare Function gpv Lib "Propellent" Alias "GetPropellerVersion" () As IntPtr
<DllImport("Propellent", EntryPoint:="SetLibraryPath", CallingConvention:=CallingConvention.Cdecl)>
Private Shared Sub setlib(ByVal lp As IntPtr)
End Sub
To init propellent I used
Dim ptr As IntPtr
Dim x As String = Nothing
hwnd = Me.Handle
ptr = Marshal.StringToHGlobalAnsi(x)
start(hwnd, False, ptr)
To send string i used the following
Dim ptr As IntPtr
Dim x As String = Nothing
x = "c:\zzz"
ptr = Marshal.StringToHGlobalAnsi(x)
setlib(ptr)
To receive string
Dim ptr As IntPtr
Dim x As String = Nothing
ptr = gpv() 'get propeller version
x = Marshal.PtrToStringAnsi(ptr)
MsgBox(x)
I'm still playing around with code but this appears to have solved all issues.
Thanks for your help and ideas guys.
Now I can finally gets some sleep.....
Regards Brian
Jeff T.
EDIT : I have replaced the existing declarations with DllImports and looked at your suggestions on variable size everything seems to be working as it should. I did not use the msgbox for the gpv() not sure if that is needed , overall very pleasing.