0
votes

I have the following function from a c++ header file:

__int16 __stdcall s_em4305_login (HANDLE m_hUSB, int DataRate, UCHAR * password);

When I run the VB equavelent:

Private Declare Function RF_EM4305_Login Lib "SRF32.dll" Alias "s_em4305_login" (ByVal handle As Long, ByVal DataRate As Long, ByRef bytes As Byte) As Integer 

I get -1100 back as a value

When I run the c# equavilent:

[DllImport("SRF32.dll", EntryPoint = "s_em4305_login")]
private static extern ushort RF_EM4305_Login(IntPtr handle, int DataRate,byte[] password);  

I get a different value. The 3rd paramater is most likely declared incorrectly. Can someone please assist in converting the c++ declaration to c#

Update

I have added some additional declarations

private static extern ushort RF_EM4305_Login(IntPtr handle, int DataRate,IntPtr password);
private static extern ushort RF_EM4305_Login(IntPtr handle, int DataRate,ref byte[] password);

With all 3 c# declarations I get the value "64436" returned.

1
Return type should be System.Int16 aka Short. Integer was 16 bit back in Classic VB, but not in VB.NET. Similarly, second parameter should be System.Int32 aka Integer. Long was 32 bits in Classic VB, but that too changed in VB.NET. And the first parameter has problems, and should use System.IntPtr as does the C# declaration. Different results between VB.NET and C# do not imply your C# declaration is in error... on the contrary it appears the C# declaration is correct and the VB.NET call is erroneous.Ben Voigt
As general advice, never use the language keyword for types in p/invoke declarations. Instead, use the names of the types in the System namespace, which explicitly describe the size.Ben Voigt
@jwdonahue: Probably string along with CharSet.Ansi would be easier to use, but byte[] is not incorrect.Ben Voigt
Try System.Int16 (or short) instead of ushort for the return type in C#. I thought you meant the return value was actually different, not just the same bit pattern treated unsigned...Ben Voigt
@felix-b: All C++ compilers made for Windows platforms that can run C# code use 32-bit int and 32-bit long.Ben Voigt

1 Answers

0
votes

If your unmanged code treats the password as a Null-terminated ansi string, this two should both work.

[DllImport("SRF32.dll", EntryPoint = "s_em4305_login", CharSet = CharSet.Ansi)]
private static extern short RF_EM4305_Login(IntPtr handle, int DataRate, string password);

[DllImport("SRF32.dll", EntryPoint = "s_em4305_login")]
private static extern short RF_EM4305_Login(IntPtr handle, int DataRate, [MarshalAs(UnmanagedType.LPStr)]string password);

And your C# declaration wasn't wrong either, because ushort 64436 equers short -1100 in memory.