P/Invoke struct some values incorrect

L

Lorraine

Hi,

I am writing a wrapper for a C library to make it into a DLL and then
using P/Invoke on that DLL. My problem is that some of the values in a
structure passed by reference are funky, while other values are correct
and the function returned from the library as successful. The flow of
the structure goes like this:
1) Create the structure in VB.NET
2) P/Invoke the DLL, pass structure by reference
3) DLL passes the structure to the C library
4) I view the structure in debugger, and noticed some correct values
and some funky ones

I am pretty sure I have narrowed the problem down to the return of the
structure from the DLL to VB.NET. This is because I tried creating the
structure in the DLL, call the library function, and then return a
DWORD value within that structure. The value returned correctly. I
also tried creating the structure in the DLL, call the library
function, and then set a DWORD value from the locally created structure
to the structure passed from VB.NET. The value was still wrong.

The values that I know are wrong are channel, txPower, and bitrate.
One of the values I know is correct is the AP_MAC. Since the layout of
the struct is sequential, I would think the values before that should
be correct.

I am out of ideas and really can't figure out why.

Thanks in advance!
Lorraine

The structure definition in C:
typedef struct _CF10G_STATUS {
CARDSTATE cardState;
char configName[CONFIG_NAME_SZ];
UCHAR client_MAC[6];
UCHAR client_IP[4];
char clientName[CLIENT_NAME_SZ];
UCHAR AP_MAC[6];
UCHAR AP_IP[4];
char APName[CLIENT_NAME_SZ];
EAPTYPE eapType;
DWORD channel;
int rssi;
BITRATE bitRate;
int txPower;
DWORD driverVersion;
} CF10G_STATUS;

The wrapper DLL's function:
extern "C" __declspec(dllexport) SDCERR VGetCurrentStatus(CF10G_STATUS
&status)
{
return GetCurrentStatus(&status);
}
The structure definition in VB.NET (EAPTYPE and BITRATE are enums)

<StructLayout(LayoutKind.Sequential)> _
Public Structure CF10G_STATUS
Public cardState As CARDSTATE

'Need to convert from ASCII Byte Array, use
ASCIIByteArrayToString
<MarshalAs(UnmanagedType.ByValArray,
SizeConst:=CONFIG_NAME_SZ)> _
Public configName As Byte() 'char configName[CONFIG_NAME_SZ]

'In decimal form, must convert each individual byte to hex
<MarshalAs(UnmanagedType.ByValArray, SizeConst:=6)> _
Public client_MAC As Byte() 'uchar client_MAC[6]

'Can be used as is
<MarshalAs(UnmanagedType.ByValArray, SizeConst:=4)> _
Public client_IP As Byte() 'uchar client_IP[4]

'Need to convert from ASCII Byte Array, use
ASCIIByteArrayToString
<MarshalAs(UnmanagedType.ByValArray,
SizeConst:=CLIENT_NAME_SZ)> _
Public clientName As Byte() 'char clientName[CLIENT_NAME_SZ]

'In decimal form, must convert each individual byte to hex
<MarshalAs(UnmanagedType.ByValArray, SizeConst:=6)> _
Public AP_MAC As Byte() 'UCHAR AP_MAC[6]

<MarshalAs(UnmanagedType.ByValArray, SizeConst:=4)> _
Public AP_IP As Byte() 'UCHAR AP_IP[4]

<MarshalAs(UnmanagedType.ByValArray,
SizeConst:=CLIENT_NAME_SZ)> _
Public APName As Byte() 'char APName[CLIENT_NAME_SZ]

Public eapType As EAPTYPE
Public channel As UInt32
Public rssi As Int32
Public bitRate As BITRATE
Public txPower As Int32
Public driverVersion As UInt32
End Structure

I get something this returned to me, even though I know channel is
supposed to be 6.

- statusStruct {SummitWrapperTest.Form1.CF10G_STATUS} SummitWrapperTest.Form1.CF10G_STATUS
+ AP_IP {Length=4} Byte()
+ AP_MAC {Length=6} Byte()
+ APName {Length=17} Byte()
bitRate 838860800 SummitWrapperTest.Form1.BITRATE
cardState CARDSTATE_ASSOCIATED {2} SummitWrapperTest.Form1.CARDSTATE
channel 3506438144 UInteger
+ client_IP {Length=4} Byte()
+ client_MAC {Length=6} Byte()
+ clientName {Length=17} Byte()
+ configName {Length=33} Byte()
driverVersion 258 UInteger
eapType EAP_NONE {0} SummitWrapperTest.Form1.EAPTYPE
rssi 385875967 Integer
txPower 117440512 Integer
 
A

Alex Yakhnin

What do you do with this structure in your C code? Keep in mind that when
the marshaler passes the structure to the native code it pins it for the
length of the call.

--
Alex Yakhnin, Device Application Developer MVP
http://blog.opennetcf.org/ayakhnin

Lorraine said:
Hi,

I am writing a wrapper for a C library to make it into a DLL and then
using P/Invoke on that DLL. My problem is that some of the values in a
structure passed by reference are funky, while other values are correct
and the function returned from the library as successful. The flow of
the structure goes like this:
1) Create the structure in VB.NET
2) P/Invoke the DLL, pass structure by reference
3) DLL passes the structure to the C library
4) I view the structure in debugger, and noticed some correct values
and some funky ones

I am pretty sure I have narrowed the problem down to the return of the
structure from the DLL to VB.NET. This is because I tried creating the
structure in the DLL, call the library function, and then return a
DWORD value within that structure. The value returned correctly. I
also tried creating the structure in the DLL, call the library
function, and then set a DWORD value from the locally created structure
to the structure passed from VB.NET. The value was still wrong.

The values that I know are wrong are channel, txPower, and bitrate.
One of the values I know is correct is the AP_MAC. Since the layout of
the struct is sequential, I would think the values before that should
be correct.

I am out of ideas and really can't figure out why.

Thanks in advance!
Lorraine

The structure definition in C:
typedef struct _CF10G_STATUS {
CARDSTATE cardState;
char configName[CONFIG_NAME_SZ];
UCHAR client_MAC[6];
UCHAR client_IP[4];
char clientName[CLIENT_NAME_SZ];
UCHAR AP_MAC[6];
UCHAR AP_IP[4];
char APName[CLIENT_NAME_SZ];
EAPTYPE eapType;
DWORD channel;
int rssi;
BITRATE bitRate;
int txPower;
DWORD driverVersion;
} CF10G_STATUS;

The wrapper DLL's function:
extern "C" __declspec(dllexport) SDCERR VGetCurrentStatus(CF10G_STATUS
&status)
{
return GetCurrentStatus(&status);
}
The structure definition in VB.NET (EAPTYPE and BITRATE are enums)

<StructLayout(LayoutKind.Sequential)> _
Public Structure CF10G_STATUS
Public cardState As CARDSTATE

'Need to convert from ASCII Byte Array, use
ASCIIByteArrayToString
<MarshalAs(UnmanagedType.ByValArray,
SizeConst:=CONFIG_NAME_SZ)> _
Public configName As Byte() 'char configName[CONFIG_NAME_SZ]

'In decimal form, must convert each individual byte to hex
<MarshalAs(UnmanagedType.ByValArray, SizeConst:=6)> _
Public client_MAC As Byte() 'uchar client_MAC[6]

'Can be used as is
<MarshalAs(UnmanagedType.ByValArray, SizeConst:=4)> _
Public client_IP As Byte() 'uchar client_IP[4]

'Need to convert from ASCII Byte Array, use
ASCIIByteArrayToString
<MarshalAs(UnmanagedType.ByValArray,
SizeConst:=CLIENT_NAME_SZ)> _
Public clientName As Byte() 'char clientName[CLIENT_NAME_SZ]

'In decimal form, must convert each individual byte to hex
<MarshalAs(UnmanagedType.ByValArray, SizeConst:=6)> _
Public AP_MAC As Byte() 'UCHAR AP_MAC[6]

<MarshalAs(UnmanagedType.ByValArray, SizeConst:=4)> _
Public AP_IP As Byte() 'UCHAR AP_IP[4]

<MarshalAs(UnmanagedType.ByValArray,
SizeConst:=CLIENT_NAME_SZ)> _
Public APName As Byte() 'char APName[CLIENT_NAME_SZ]

Public eapType As EAPTYPE
Public channel As UInt32
Public rssi As Int32
Public bitRate As BITRATE
Public txPower As Int32
Public driverVersion As UInt32
End Structure

I get something this returned to me, even though I know channel is
supposed to be 6.

- statusStruct {SummitWrapperTest.Form1.CF10G_STATUS}
SummitWrapperTest.Form1.CF10G_STATUS
+ AP_IP {Length=4} Byte()
+ AP_MAC {Length=6} Byte()
+ APName {Length=17} Byte()
bitRate 838860800 SummitWrapperTest.Form1.BITRATE
cardState CARDSTATE_ASSOCIATED {2} SummitWrapperTest.Form1.CARDSTATE
channel 3506438144 UInteger
+ client_IP {Length=4} Byte()
+ client_MAC {Length=6} Byte()
+ clientName {Length=17} Byte()
+ configName {Length=33} Byte()
driverVersion 258 UInteger
eapType EAP_NONE {0} SummitWrapperTest.Form1.EAPTYPE
rssi 385875967 Integer
txPower 117440512 Integer
 
L

Lorraine

Hi Alex,

Thanks for replying. As I have said in the email, I unfortunately do
not have access to the code. Though does it seem like the C library is
to blame? I was ruling that out because even when I set one of the
values in the structure in the wrapper, it was still returning wrong.

Thanks,
Lorraine


Alex said:
What do you do with this structure in your C code? Keep in mind that when
the marshaler passes the structure to the native code it pins it for the
length of the call.

--
Alex Yakhnin, Device Application Developer MVP
http://blog.opennetcf.org/ayakhnin

Lorraine said:
Hi,

I am writing a wrapper for a C library to make it into a DLL and then
using P/Invoke on that DLL. My problem is that some of the values in a
structure passed by reference are funky, while other values are correct
and the function returned from the library as successful. The flow of
the structure goes like this:
1) Create the structure in VB.NET
2) P/Invoke the DLL, pass structure by reference
3) DLL passes the structure to the C library
4) I view the structure in debugger, and noticed some correct values
and some funky ones

I am pretty sure I have narrowed the problem down to the return of the
structure from the DLL to VB.NET. This is because I tried creating the
structure in the DLL, call the library function, and then return a
DWORD value within that structure. The value returned correctly. I
also tried creating the structure in the DLL, call the library
function, and then set a DWORD value from the locally created structure
to the structure passed from VB.NET. The value was still wrong.

The values that I know are wrong are channel, txPower, and bitrate.
One of the values I know is correct is the AP_MAC. Since the layout of
the struct is sequential, I would think the values before that should
be correct.

I am out of ideas and really can't figure out why.

Thanks in advance!
Lorraine

The structure definition in C:
typedef struct _CF10G_STATUS {
CARDSTATE cardState;
char configName[CONFIG_NAME_SZ];
UCHAR client_MAC[6];
UCHAR client_IP[4];
char clientName[CLIENT_NAME_SZ];
UCHAR AP_MAC[6];
UCHAR AP_IP[4];
char APName[CLIENT_NAME_SZ];
EAPTYPE eapType;
DWORD channel;
int rssi;
BITRATE bitRate;
int txPower;
DWORD driverVersion;
} CF10G_STATUS;

The wrapper DLL's function:
extern "C" __declspec(dllexport) SDCERR VGetCurrentStatus(CF10G_STATUS
&status)
{
return GetCurrentStatus(&status);
}
The structure definition in VB.NET (EAPTYPE and BITRATE are enums)

<StructLayout(LayoutKind.Sequential)> _
Public Structure CF10G_STATUS
Public cardState As CARDSTATE

'Need to convert from ASCII Byte Array, use
ASCIIByteArrayToString
<MarshalAs(UnmanagedType.ByValArray,
SizeConst:=CONFIG_NAME_SZ)> _
Public configName As Byte() 'char configName[CONFIG_NAME_SZ]

'In decimal form, must convert each individual byte to hex
<MarshalAs(UnmanagedType.ByValArray, SizeConst:=6)> _
Public client_MAC As Byte() 'uchar client_MAC[6]

'Can be used as is
<MarshalAs(UnmanagedType.ByValArray, SizeConst:=4)> _
Public client_IP As Byte() 'uchar client_IP[4]

'Need to convert from ASCII Byte Array, use
ASCIIByteArrayToString
<MarshalAs(UnmanagedType.ByValArray,
SizeConst:=CLIENT_NAME_SZ)> _
Public clientName As Byte() 'char clientName[CLIENT_NAME_SZ]

'In decimal form, must convert each individual byte to hex
<MarshalAs(UnmanagedType.ByValArray, SizeConst:=6)> _
Public AP_MAC As Byte() 'UCHAR AP_MAC[6]

<MarshalAs(UnmanagedType.ByValArray, SizeConst:=4)> _
Public AP_IP As Byte() 'UCHAR AP_IP[4]

<MarshalAs(UnmanagedType.ByValArray,
SizeConst:=CLIENT_NAME_SZ)> _
Public APName As Byte() 'char APName[CLIENT_NAME_SZ]

Public eapType As EAPTYPE
Public channel As UInt32
Public rssi As Int32
Public bitRate As BITRATE
Public txPower As Int32
Public driverVersion As UInt32
End Structure

I get something this returned to me, even though I know channel is
supposed to be 6.

- statusStruct {SummitWrapperTest.Form1.CF10G_STATUS}
SummitWrapperTest.Form1.CF10G_STATUS
+ AP_IP {Length=4} Byte()
+ AP_MAC {Length=6} Byte()
+ APName {Length=17} Byte()
bitRate 838860800 SummitWrapperTest.Form1.BITRATE
cardState CARDSTATE_ASSOCIATED {2} SummitWrapperTest.Form1.CARDSTATE
channel 3506438144 UInteger
+ client_IP {Length=4} Byte()
+ client_MAC {Length=6} Byte()
+ clientName {Length=17} Byte()
+ configName {Length=33} Byte()
driverVersion 258 UInteger
eapType EAP_NONE {0} SummitWrapperTest.Form1.EAPTYPE
rssi 385875967 Integer
txPower 117440512 Integer
 

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