C dll reference/call works in VB6, not working in VB.NET

J

John

I am trying to call a third party company's dll that I have no control
over. They tell me it was written in C. The declaration in VB6 is as
follows:

Private Declare Sub csub Lib "rlpolk.dll" (ByVal T_VININ As String, _
ByVal T_VINOUT As String, ByVal i_bypass As
Integer)

The T_VININ string is 25 characters and the T_VINOUT string is 108. I
have tried to convert the declaration to VB.NET with little success:

Class Polk
<DllImport("c:\rlpolk.dll", EntryPoint:="microvin", _
SetLastError:=True, CharSet:=CharSet.Unicode, _
ExactSpelling:=True, _
CallingConvention:=CallingConvention.StdCall)> _
Public Shared Function csub(ByVal T_VININ As String, _
ByVal T_VINOUT As String, ByVal i_byPass As Integer)
End Function
End Class

The call to the routine is:

Polk.csub(T_VININ, T_VINOUT, 98)

When I do this, I get the message that PInvoke cannot return a
Variant.

If I change it to a Sub, the call to the routine returns nothing.
T_VININ is the variable sent to the routine and T_VINOUT should be the
return string. (T_VININ is a VIN number and T_VINOUT is a 108
character explosion of the vin.)

I have tried many combinations including trying to Marshal the
strings, but all have failed. Please help. Thank you.

John Germani
 
N

Nick Hall

A couple of things immediately spring to mind: -

1. It definitely needs to be a Sub!
2. The original VB6 declaration causes the strings to be passed as ANSI
strings rather than Unicode strings (you couldn't directly pass strings as
Unicode using a Declare). Therefore I think the CharSet needs to be
Charset.Ansi.
3. As strings are immutable in VB.NET you should probably declare them As
StringBuilder instead of String. This will ensure that P/Invoke will copy
the data into StringBuilder objects once the call has completed.
4. i_ByPass was declared As Integer in the original, meaning it needs to be
declared As Short in VB.NET (Integer is now 32 bits rather than 16)
5. I notice there is no Alias in the VB6 declaration (which would be the
equivalent of the EntryPoint field). Was this an omission?

That being said I think your declaration needs to look something like the
following: -

Imports System.Text

Class Polk
<DllImport("rlpolk.dll", EntryPoint:="microvin", _
SetLastError:=True, CharSet:=CharSet.Ansi, _
ExactSpelling:=True, _
CallingConvention:=CallingConvention.StdCall)> _
Public Shared Sub csub(ByVal T_VININ As StringBuilder, _
ByVal T_VINOUT As StringBuilder, ByVal i_byPass As Short)
End Function
End Class

And call it like this: -

Dim T_VININ as new StringBuilder(255)
Dim T_VINOUT as new StringBuilder(108)
Polk.csub(T_VININ, T_VINOUT, 98)

I hope this helps,

Nick Hall
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Top