Trouble with 3rd party dll wrapper class

M

Mercy

Hey All,

This is probably a easy question, but I'm really stuck. I have a
command console program written in C++, that I want to convert it to C#
to make it into a windows app. The problem is that my program uses a
third part dll. So I tried to write a wrapper class for it. Even
though I think my interface looks right... the values being returned
from the third party imported functions are off.

Original Code:

#define USBCAN_ANY_MODULE = 255;

// *********Function prototypes from 3rd party header
BYTE PUBLIC UcanInitHardware( byte* handle, byte deviceNum, byte
callType );
BYTE PUBLIC UcanGetHardwareInfo( byte handle, tUcanHardwareInfo* info
);

//*********Structures from 3rd party header
typedef struct
{
BYTE m_bDeviceNr;
BYTE m_UcanHandle;
DWORD m_dwReserved;
BYTE m_bBTR0;
BYTE m_bBTR1;
BYTE m_bOCR;
DWORD m_dwAMR;
DWORD m_dwACR;

// new values since 17.03.03 Version V2.16
BYTE m_bMode;
DWORD m_dwSerialNr;

} tUcanHardwareInfo;

//*********Original code fragment from main()
main()
{
byte handle;
tUcanHardwareInfo hardwrMsg;

UcanInitHardware ( &handle, USBCAN_ANY_MODULE, NULL );
UcanGetHardwareInfo( &handle, hardwrMsg)
}

// *********Original results
m_bDeviceNr = 0;
m_UcanHandle = 1;
m_dwReserved = N/A;
m_bBTR0 = 1;
m_bBTR1 = 28;
m_bOCR = 26;
m_dwAMR = 0xFFFFFFFF;
m_dwACR = 0;

// new values since 17.03.03 Version V2.16
m_bMode = 0;
m_dwSerialNr = 0x5FFE7;

//********* Here's my attempt at importing the DLL functions
public const int USBCAN_ANY_MODULE = 255;

[DllImport("USBCAN32.dll", EntryPoint="UcanInitHardware" )]
public static extern byte UcanInitHardware( ref byte handle, byte
DeviceNum, byte fpCallbackFkt_p);

[DllImport("USBCAN32.dll" )]
public static extern byte UcanGetHardwareInfo(byte UcanHandle_p, ref
Structures.tUcanHardwareInfo pHwInfo_p);

[ StructLayout( LayoutKind.Sequential )]
public struct tUcanHardwareInfo
{
public byte m_bDeviceNr;
public byte m_UcanHandle;
public uint m_dwReserved;
public byte m_bBTR0;
public byte m_bBTR1;
public byte m_bOCR;
public uint m_dwAMR;
public uint m_dwACR;

// new values since 17.03.03 Version V2.16
public byte m_bMode;
public uint m_dwSerialNr;
}

//********* New main()
main()
{
byte UcanHandle = 0;
Structures.tUcanHardwareInfo hardwrMsg = new
Structures.tUcanHardwareInfo();

USBCAN32.UcanInitHardware(ref UcanHandle, USBCAN_ANY_MODULE,
0);
USBCAN32.UcanGetHardwareInfo( UcanHandle, ref hardwrMsg );

}

//********* New results
m_bDeviceNr = 0;
m_UcanHandle = 1;
m_dwReserved = N/A;
m_bBTR0 = 26;
m_bBTR1 = 0xFF;
m_bOCR = 0xFF;
m_dwAMR = 0xFFE7;
m_dwACR = 0xFF;

// new values since 17.03.03 Version V2.16
m_bMode = 5;
m_dwSerialNr = 0;


It seems that the results from "UcanGetHardwareInfo" are not being
returned into the correct fields of structure tUcanHardwareInfo. I
also noticed that if I put the 5 of variable m_bMode with m_dwAMR, it
could = 0x5FFE7 .... which is the expected value of m_dwSerialNr. So
does anyone have any idea what I'm doing wrong for the structure's
fields to get so confused ?
 
F

Fabio Cannizzo

Hi Mercy.

I think you might be experiencing a problem with byte alignment.

When you comile C++ code, the compiler allows you to specify how you want to
align your data (i.e. byte, word, doubleword, quadword... ). For instance,
if you specify word, the compiler try to allocate every field of a structure
at an even memory address, so if your structure contains a char and an int,
the compiler will insert an empty char of padding after the byte. If you
chose double word, the compiler try to allocate everything at a memory
address multiple of four and so on...
This is done for efficiency reasons, which are related to the design of the
CPU and the way it accesses memory and cache. This is a long story which
won't go into, but you can read the Assembler guides available on Intel web
site if you want to know more. Or search goolge for "cache split fault",
whihc will give an idea.

However, in your code you specify "layoutsequantial". This is equivakent to
byte alignment, but clearly this is not the way your dll was compiled. You
need to reverse engineer what is the correct alignment to be used.

Cheers,
Fabio


Mercy said:
Hey All,

This is probably a easy question, but I'm really stuck. I have a
command console program written in C++, that I want to convert it to C#
to make it into a windows app. The problem is that my program uses a
third part dll. So I tried to write a wrapper class for it. Even
though I think my interface looks right... the values being returned
from the third party imported functions are off.

Original Code:

#define USBCAN_ANY_MODULE = 255;

// *********Function prototypes from 3rd party header
BYTE PUBLIC UcanInitHardware( byte* handle, byte deviceNum, byte
callType );
BYTE PUBLIC UcanGetHardwareInfo( byte handle, tUcanHardwareInfo* info
);

//*********Structures from 3rd party header
typedef struct
{
BYTE m_bDeviceNr;
BYTE m_UcanHandle;
DWORD m_dwReserved;
BYTE m_bBTR0;
BYTE m_bBTR1;
BYTE m_bOCR;
DWORD m_dwAMR;
DWORD m_dwACR;

// new values since 17.03.03 Version V2.16
BYTE m_bMode;
DWORD m_dwSerialNr;

} tUcanHardwareInfo;

//*********Original code fragment from main()
main()
{
byte handle;
tUcanHardwareInfo hardwrMsg;

UcanInitHardware ( &handle, USBCAN_ANY_MODULE, NULL );
UcanGetHardwareInfo( &handle, hardwrMsg)
}

// *********Original results
m_bDeviceNr = 0;
m_UcanHandle = 1;
m_dwReserved = N/A;
m_bBTR0 = 1;
m_bBTR1 = 28;
m_bOCR = 26;
m_dwAMR = 0xFFFFFFFF;
m_dwACR = 0;

// new values since 17.03.03 Version V2.16
m_bMode = 0;
m_dwSerialNr = 0x5FFE7;

//********* Here's my attempt at importing the DLL functions
public const int USBCAN_ANY_MODULE = 255;

[DllImport("USBCAN32.dll", EntryPoint="UcanInitHardware" )]
public static extern byte UcanInitHardware( ref byte handle, byte
DeviceNum, byte fpCallbackFkt_p);

[DllImport("USBCAN32.dll" )]
public static extern byte UcanGetHardwareInfo(byte UcanHandle_p, ref
Structures.tUcanHardwareInfo pHwInfo_p);

[ StructLayout( LayoutKind.Sequential )]
public struct tUcanHardwareInfo
{
public byte m_bDeviceNr;
public byte m_UcanHandle;
public uint m_dwReserved;
public byte m_bBTR0;
public byte m_bBTR1;
public byte m_bOCR;
public uint m_dwAMR;
public uint m_dwACR;

// new values since 17.03.03 Version V2.16
public byte m_bMode;
public uint m_dwSerialNr;
}

//********* New main()
main()
{
byte UcanHandle = 0;
Structures.tUcanHardwareInfo hardwrMsg = new
Structures.tUcanHardwareInfo();

USBCAN32.UcanInitHardware(ref UcanHandle, USBCAN_ANY_MODULE,
0);
USBCAN32.UcanGetHardwareInfo( UcanHandle, ref hardwrMsg );

}

//********* New results
m_bDeviceNr = 0;
m_UcanHandle = 1;
m_dwReserved = N/A;
m_bBTR0 = 26;
m_bBTR1 = 0xFF;
m_bOCR = 0xFF;
m_dwAMR = 0xFFE7;
m_dwACR = 0xFF;

// new values since 17.03.03 Version V2.16
m_bMode = 5;
m_dwSerialNr = 0;


It seems that the results from "UcanGetHardwareInfo" are not being
returned into the correct fields of structure tUcanHardwareInfo. I
also noticed that if I put the 5 of variable m_bMode with m_dwAMR, it
could = 0x5FFE7 .... which is the expected value of m_dwSerialNr. So
does anyone have any idea what I'm doing wrong for the structure's
fields to get so confused ?
 
Top