Calling older VB dll (possibly fixed length string)
Hi
Got a dll from a supplier that I need to call. His declaration is
Declaration with Microsoft Visual Basic®:
Declare Function CopyThresholds Lib “OHK43.DLL“ _
(ByVal I_Flags As Long, ByVal I_Ref As String, ByVal I_T0 As Double, _
ByVal I_CR As Single, ByVal I_Range As Long _
ByRef O_TCmin As Double, ByRef O_TCmax As Double, _
ByVal O_Err As String, ByRef O_SzErr As Long) As Long
Buffer variable in calling program:
Dim O_Err As String * 20
Now, the Sting * 20 is clearly not VB.NET, and sure enough it crashes when run - "Attempt to read or write in protected memory" and that leads me to think that there is something with that string definition - or possibly the I_Ref definition which hasn't been defined as fixed length.
I've tried <VBFixedString(20)> when defining O_Err, but I have a feeling that it might not be enough when the function declaration is like that (not specifically fixed length). I cannot figure out how to specify this correctly.
As a small hmmmm, the above is pasted directly from the suppliers documentation, but that't will never work, as there is a "," missing after I_Range as long... Clearly not something he has pasted from a working program...
Comments or suggestions ??
I know - I could contact the supplier, but I'd rather make a complete ass of myself here that with him...
Thanks
Thomas
Re: Calling older VB dll (possibly fixed length string)
Just prepare your string before calling the API:
Dim O_Err As String = Space(20)
By the way, native Windows API does not have such data type as fixed string.
Re: Calling older VB dll (possibly fixed length string)
Nope, sorry - doesn't change a thing.
Re: Calling older VB dll (possibly fixed length string)
Re: Calling older VB dll (possibly fixed length string)
If that was a VB6 declaration you should change Long to Integer in order to call it:
Code:
Declare Function CopyThresholds Lib "OHK43.DLL" _
(ByVal I_Flags As Integer, ByVal I_Ref As String, ByVal I_T0 As Double, _
ByVal I_CR As Single, ByVal I_Range As Integer, _
ByRef O_TCmin As Double, ByRef O_TCmax As Double, _
ByVal O_Err As String, ByRef O_SzErr As Integer) As Integer
O_SzErr must be O_Err.Length and the O_Err must be long enough to hold the whole error message
Re: Calling older VB dll (possibly fixed length string)
Declare Function CopyThresholds Lib "OHK43.DLL" _
(ByVal I_Flags As Integer, ByVal I_Ref As String, ByVal I_T0 As Double, _
ByVal I_CR As Single, ByVal I_Range As Integer, _
ByRef O_TCmin As Double, ByRef O_TCmax As Double, _
ByRef O_Err As String, ByRef O_SzErr As Integer) As Integer
Public Sub Test()
Dim I_Flags As Integer = 0
Dim I_Ref As String = "R404A" & Chr(0)
Dim I_T0 = 10.0
Dim I_CR As Single = 100
Dim I_Range As Integer = 0
Dim O_TCmin As Double = 0
Dim O_TCmax As Double = 0
Dim O_Err As String = Space(19) & Chr(0)
Dim O_SzErr As Integer = O_Err.Length
Dim ret As Integer = CopyThresholds(I_Flags, I_Ref, I_T0, I_CR, I_Range, O_TCmin, O_TCmax, O_Err, O_SzErr)
End Sub
This is what I do - it fails too.
Any double/single issues between VB6 and .Net (didn't know the long/integer as I never did VB6)
Re: Calling older VB dll (possibly fixed length string)
The reason for Long/Integer values is that Integers are 32 bit in VB.Net while they were 16 bit in VB6. To supplement the 16 bit Integer there is a Short data type.
OK, back to the topic, does your documentation have a plain C/C++ declaration?
Re: Calling older VB dll (possibly fixed length string)
Hold on !!!
You have ByVal on O_Err and I had ByRef and that solved (at least the crashing) problem.
Why is ByVal correct ??
Re: Calling older VB dll (possibly fixed length string)
Because with ByVal you supply a pointer LPCTSTR (or LPCWSTR) and with ByRef you supply a pointer to a pointer (i think that it's called BSTR but I could be wrong).
That's why I asked for C++ declaration - to check whether the declaration string you provided is correct. It's easier with native Win32API but it can be tough with third party DLLs
Re: Calling older VB dll (possibly fixed length string)