c# CP210x Wrapper InteropServices IntPtr HandleRef problem

J

justin.kruger

I am having a problem with exchanging handles with c# and the
"CP210xManufacturing.dll" in a device wrapper that i am working on.

I have created a wrapper class to address some of the functions in the
dll, but not all of them yet. To my knowledge they should be almost
correct, however this is my first try at exchanging handles between
legacy code and a managed enviroment. It seems that I am able to get a
handle from "CP210x_Open," however, I am not able to connect to a
device using this handle for any further informaiton like
CP210x_GetDeviceVid.

the "getNumDevice(ref numDevice)" works just fine, so the assumption is
that the onlything that could be wrong in "getDevicePid(ref siRef, ref
pid)" is then in the "ref siRef". I am unsure if i am marshaling it
correctly or if i am using the right level of indirection to get a
value, but i am getting a value in "open(0, ref siRef)" for siRef so i
would think that is close. However, the value that I get in c# is
different than the value I get in c++.

In c++ the value seems to be constant, and in c# the value seems hover
around a simular value, but is different each time without a logical
progression.

in c++ i almost always get a value 0x7b8 in my handle
/* //C++ code
HANDLE myDevice = {0};
status = CP210x_Open(0, &myDevice);
//myDevice = 0x7b8;
*/

class CSepSIChipWrap
{
private const string CP210xManu = "CP210xManufacturing.dll";

[DllImport(CP210xManu, EntryPoint = "CP210x_GetNumDevices")]
public static extern int getNumDevices(
[In, Out] ref UInt32 deviceNumb);

[DllImport(CP210xManu, EntryPoint = "CP210x_Open")]
public static extern int open(
[In] UInt32 deviceNumb,
[In, Out] ref IntPtr deviceHandle);

[DllImport(CP210xManu, EntryPoint = "CP210x_Close")]
public static extern int close(
[In, Out] ref IntPtr deviceHandle);

[DllImport(CP210xManu, EntryPoint = "CP210x_GetDeviceProductString",
CharSet = CharSet.Ansi)]
public static extern int getDeviceProductString(
[In, Out] ref IntPtr deviceHandle,
[In, Out] ref StringBuilder Product,
[In, Out] ref byte Length,
[In] bool ConvertToASCII);

[DllImport(CP210xManu, EntryPoint = "CP210x_GetDeviceSerialNumber",
CharSet = CharSet.Ansi)]
public static extern int getDeviceSerialNumber(
[In, Out] ref IntPtr deviceHandle,
[In, Out] ref StringBuilder Product,
[In, Out] ref byte Length,
[In, Out] bool ConvertToASCII);

[DllImport(CP210xManu, EntryPoint = "CP210x_GetDeviceVid")]
public static extern int getDeviceVid(
[In, Out] ref IntPtr deviceHandle,
[In, Out] ref ushort Vid);

[DllImport(CP210xManu, EntryPoint = "CP210x_GetDevicePid")]
public static extern int getDevicePid(
[In, Out] ref IntPtr deviceHandle,
[In, Out] ref ushort Pid);
}

void loadSettings(){
IntPtr siRef = IntPtr.Zero;
int result = 0;
uint numDevice = 0;
result = DeviceWrappers.CSepSIChipWrap.getNumDevices(ref numDevice);

result = DeviceWrappers.CSepSIChipWrap.open(0, ref siRef);
ushort pid = 0;
result = DeviceWrappers.CSepSIChipWrap.getDevicePid(ref siRef, ref
pid);
//lbDevicePID is a .net text label on a user control
this.lbDevicePID.Text = pid.ToString();
}
 
W

Willy Denoyette [MVP]

|I am having a problem with exchanging handles with c# and the
| "CP210xManufacturing.dll" in a device wrapper that i am working on.
|
| I have created a wrapper class to address some of the functions in the
| dll, but not all of them yet. To my knowledge they should be almost
| correct, however this is my first try at exchanging handles between
| legacy code and a managed enviroment. It seems that I am able to get a
| handle from "CP210x_Open," however, I am not able to connect to a
| device using this handle for any further informaiton like
| CP210x_GetDeviceVid.
|
| the "getNumDevice(ref numDevice)" works just fine, so the assumption is
| that the onlything that could be wrong in "getDevicePid(ref siRef, ref
| pid)" is then in the "ref siRef". I am unsure if i am marshaling it
| correctly or if i am using the right level of indirection to get a
| value, but i am getting a value in "open(0, ref siRef)" for siRef so i
| would think that is close. However, the value that I get in c# is
| different than the value I get in c++.
|
| In c++ the value seems to be constant, and in c# the value seems hover
| around a simular value, but is different each time without a logical
| progression.
|
| in c++ i almost always get a value 0x7b8 in my handle
| /* //C++ code
| HANDLE myDevice = {0};
| status = CP210x_Open(0, &myDevice);
| //myDevice = 0x7b8;
| */
|
| class CSepSIChipWrap
| {
| private const string CP210xManu = "CP210xManufacturing.dll";
|
| [DllImport(CP210xManu, EntryPoint = "CP210x_GetNumDevices")]
| public static extern int getNumDevices(
| [In, Out] ref UInt32 deviceNumb);
|
| [DllImport(CP210xManu, EntryPoint = "CP210x_Open")]
| public static extern int open(
| [In] UInt32 deviceNumb,
| [In, Out] ref IntPtr deviceHandle);
|
| [DllImport(CP210xManu, EntryPoint = "CP210x_Close")]
| public static extern int close(
| [In, Out] ref IntPtr deviceHandle);
|
| [DllImport(CP210xManu, EntryPoint = "CP210x_GetDeviceProductString",
| CharSet = CharSet.Ansi)]
| public static extern int getDeviceProductString(
| [In, Out] ref IntPtr deviceHandle,
| [In, Out] ref StringBuilder Product,
| [In, Out] ref byte Length,
| [In] bool ConvertToASCII);
|
| [DllImport(CP210xManu, EntryPoint = "CP210x_GetDeviceSerialNumber",
| CharSet = CharSet.Ansi)]
| public static extern int getDeviceSerialNumber(
| [In, Out] ref IntPtr deviceHandle,
| [In, Out] ref StringBuilder Product,
| [In, Out] ref byte Length,
| [In, Out] bool ConvertToASCII);
|
| [DllImport(CP210xManu, EntryPoint = "CP210x_GetDeviceVid")]
| public static extern int getDeviceVid(
| [In, Out] ref IntPtr deviceHandle,
| [In, Out] ref ushort Vid);
|
| [DllImport(CP210xManu, EntryPoint = "CP210x_GetDevicePid")]
| public static extern int getDevicePid(
| [In, Out] ref IntPtr deviceHandle,
| [In, Out] ref ushort Pid);
| }
|
| void loadSettings(){
| IntPtr siRef = IntPtr.Zero;
| int result = 0;
| uint numDevice = 0;
| result = DeviceWrappers.CSepSIChipWrap.getNumDevices(ref numDevice);
|
| result = DeviceWrappers.CSepSIChipWrap.open(0, ref siRef);
| ushort pid = 0;
| result = DeviceWrappers.CSepSIChipWrap.getDevicePid(ref siRef, ref
| pid);
| //lbDevicePID is a .net text label on a user control
| this.lbDevicePID.Text = pid.ToString();
| }
|

There is no easy way for us to give you some hint as long as you don't post
the C++ function prototypes and type declarations, and, as long as you don't
say what goes wrong. Telling that a value of a 'handle' is different in C#
then in C++ isn't very informative, OS handles have no fixed values, they
are opaque pointers into the process handle table, so they can differ from
one application to another even if you are pointing to the same device or
whatever the handle is used for.

Willy.
 
J

justin.kruger

here is a link to the full function documentation, i have included some
of it below from the pdf
http://www.silabs.com/public/documents/tpub_doc/anote/Microcontrollers/Interface/en/an144.pdf

here is the function durring debug
void loadSettings(){
IntPtr siRef = IntPtr.Zero;
int result = 0;
uint numDevice = 0;
result = DeviceWrappers.CSepSIChipWrap.getNumDevices(ref numDevice);
//result = 0 after execute
result = DeviceWrappers.CSepSIChipWrap.open(0, ref siRef); //result =
0 after execute
ushort pid = 0;
result = DeviceWrappers.CSepSIChipWrap.getDevicePid(ref siRef, ref
pid); //result = 3 after execute "Device IO Failed"
//pid still equals zero at this point and should be some hex value like
0x10c4
//lbDevicePID is a .net text label on a user control
this.lbDevicePID.Text = pid.ToString();
}


the handle is the only part that seems to be way off, i use nearly the
same args for getNumDevices

5.1. CP210x_GetNumDevices
Description:This function returns the number of CP210x devices
connected to the host.
Supported Devices: CP2101, CP2102, CP2103
Location: CP210x Manufacturing DLL
Prototype: CP210x_STATUS CP210x_GetNumDevices( LPDWORD NumDevices )
Parameters: 1. NumDevices-Address of a DWORD that will contain the
number of devices.
Return Value:CP210x_STATUS=CP210x_SUCCESS,
CP210x_DEVICE_NOT_FOUND,
CP210x_INVALID_PARAMETER

5.4. CP210x_Open
Description:Opens and returns a handle to a device using a device
number determined by the number returned from CP210x_GetNumDevices().
Supported Devices: CP2101, CP2102, CP2103
Location: CP210x Manufacturing DLL
Prototype: CP210x_STATUS CP210x_Open( DWORD DeviceNum, HANDLE* Handle )
Parameters: 1. DeviceNum-Device index. 0 for the first device, 1 for
the second, etc.
2.Handle-Pointer to a variable where the handle to the device will be
stored. This handle will be used for all subsequent accesses to the
device.
Return Value:CP210x_STATUS=CP210x_SUCCESS,
CP210x_DEVICE_NOT_FOUND,
CP210x_INVALID_PARAMETER

5.5. CP210x_Close
Description:Closes an open device handle.
Supported Devices: CP2101, CP2102, CP2103
Location: CP210x Manufacturing DLL
Prototype: CP210x_STATUS CP210x_Close( HANDLE Handle )
Parameters: 1. Handle-Handle to the device to close as returned by
CP210x_Open().
Return Value:CP210x_STATUS=CP210x_SUCCESS,
CP210x_INVALID_HANDLE

5.18. CP210x_GetDevicePid
Description:Returns the 2-byte Product ID field of the Device
Descriptor contained in EEPROM of a CP210x device.
Supported Devices: CP2101, CP2102, CP2103
Location: CP210x Manufacturing DLL
Prototype: CP210x_STATUS CP210x_GetDevicePid( HANDLE Handle, LPWORD Pid
)
Parameters: 1. Handle-Handle to the device to close as returned by
CP210x_Open().
2.PID-Pointer to a 2-byte value that returns the Product ID of the
CP210x device.
Return Value:CP210x_STATUS=CP210x_SUCCESS,
CP210x_INVALID_PARAMETER,
CP210x_INVALID_HANDLE,
CP210x_DEVICE_IO_FAILED

// Return codes
#define CP210x_SUCCESS 0x00
#define CP210x_DEVICE_NOT_FOUND 0xFF
#define CP210x_INVALID_HANDLE 0x01
#define CP210x_INVALID_PARAMETER 0x02
#define CP210x_DEVICE_IO_FAILED 0x03
#define CP210x_FUNCTION_NOT_SUPPORTED 0x04
#define CP210x_GLOBAL_DATA_ERROR 0x05
#define CP210x_FILE_ERROR 0x06
#define CP210x_COMMAND_FAILED 0x08
#define CP210x_INVALID_ACCESS_TYPE 0x09
 
W

Willy Denoyette [MVP]

Look at this...

Prototype: CP210x_STATUS CP210x_GetDevicePid( HANDLE Handle, LPWORD Pid

.........getDevicePid(ref siRef, ref

you should pass the handle here, not a pointer to the handle.
getDevicePid(siRef, ref Pid..

Willy.

| here is a link to the full function documentation, i have included some
| of it below from the pdf
|
http://www.silabs.com/public/documents/tpub_doc/anote/Microcontrollers/Interface/en/an144.pdf
|
| here is the function durring debug
| void loadSettings(){
| IntPtr siRef = IntPtr.Zero;
| int result = 0;
| uint numDevice = 0;
| result = DeviceWrappers.CSepSIChipWrap.getNumDevices(ref numDevice);
| //result = 0 after execute
| result = DeviceWrappers.CSepSIChipWrap.open(0, ref siRef); //result =
| 0 after execute
| ushort pid = 0;
| result = DeviceWrappers.CSepSIChipWrap.getDevicePid(ref siRef, ref
| pid); //result = 3 after execute "Device IO Failed"
| //pid still equals zero at this point and should be some hex value like
| 0x10c4
| //lbDevicePID is a .net text label on a user control
| this.lbDevicePID.Text = pid.ToString();
| }
|
|
| the handle is the only part that seems to be way off, i use nearly the
| same args for getNumDevices
|
| 5.1. CP210x_GetNumDevices
| Description:This function returns the number of CP210x devices
| connected to the host.
| Supported Devices: CP2101, CP2102, CP2103
| Location: CP210x Manufacturing DLL
| Prototype: CP210x_STATUS CP210x_GetNumDevices( LPDWORD NumDevices )
| Parameters: 1. NumDevices-Address of a DWORD that will contain the
| number of devices.
| Return Value:CP210x_STATUS=CP210x_SUCCESS,
| CP210x_DEVICE_NOT_FOUND,
| CP210x_INVALID_PARAMETER
|
| 5.4. CP210x_Open
| Description:Opens and returns a handle to a device using a device
| number determined by the number returned from CP210x_GetNumDevices().
| Supported Devices: CP2101, CP2102, CP2103
| Location: CP210x Manufacturing DLL
| Prototype: CP210x_STATUS CP210x_Open( DWORD DeviceNum, HANDLE* Handle )
| Parameters: 1. DeviceNum-Device index. 0 for the first device, 1 for
| the second, etc.
| 2.Handle-Pointer to a variable where the handle to the device will be
| stored. This handle will be used for all subsequent accesses to the
| device.
| Return Value:CP210x_STATUS=CP210x_SUCCESS,
| CP210x_DEVICE_NOT_FOUND,
| CP210x_INVALID_PARAMETER
|
| 5.5. CP210x_Close
| Description:Closes an open device handle.
| Supported Devices: CP2101, CP2102, CP2103
| Location: CP210x Manufacturing DLL
| Prototype: CP210x_STATUS CP210x_Close( HANDLE Handle )
| Parameters: 1. Handle-Handle to the device to close as returned by
| CP210x_Open().
| Return Value:CP210x_STATUS=CP210x_SUCCESS,
| CP210x_INVALID_HANDLE
|
| 5.18. CP210x_GetDevicePid
| Description:Returns the 2-byte Product ID field of the Device
| Descriptor contained in EEPROM of a CP210x device.
| Supported Devices: CP2101, CP2102, CP2103
| Location: CP210x Manufacturing DLL
| Prototype: CP210x_STATUS CP210x_GetDevicePid( HANDLE Handle, LPWORD Pid
| )
| Parameters: 1. Handle-Handle to the device to close as returned by
| CP210x_Open().
| 2.PID-Pointer to a 2-byte value that returns the Product ID of the
| CP210x device.
| Return Value:CP210x_STATUS=CP210x_SUCCESS,
| CP210x_INVALID_PARAMETER,
| CP210x_INVALID_HANDLE,
| CP210x_DEVICE_IO_FAILED
|
| // Return codes
| #define CP210x_SUCCESS 0x00
| #define CP210x_DEVICE_NOT_FOUND 0xFF
| #define CP210x_INVALID_HANDLE 0x01
| #define CP210x_INVALID_PARAMETER 0x02
| #define CP210x_DEVICE_IO_FAILED 0x03
| #define CP210x_FUNCTION_NOT_SUPPORTED 0x04
| #define CP210x_GLOBAL_DATA_ERROR 0x05
| #define CP210x_FILE_ERROR 0x06
| #define CP210x_COMMAND_FAILED 0x08
| #define CP210x_INVALID_ACCESS_TYPE 0x09
|
 
J

justin.kruger

I tested that before with no, luck.

So, just to be sure i made the appropriate changes and tried it agian.
| class CSepSIChipWrap
| {
| private const string CP210xManu = "CP210xManufacturing.dll";
|
| [DllImport(CP210xManu, EntryPoint = "CP210x_GetNumDevices")]
| public static extern int getNumDevices(
| [In, Out] ref UInt32 deviceNumb);
|
| [DllImport(CP210xManu, EntryPoint = "CP210x_Open")]
| public static extern int open(
| [In] UInt32 deviceNumb,
| [In, Out] IntPtr deviceHandle);
|
| [DllImport(CP210xManu, EntryPoint = "CP210x_Close")]
| public static extern int close(
| [In, Out] IntPtr deviceHandle);
|
| [DllImport(CP210xManu, EntryPoint = "CP210x_GetDeviceProductString",
| CharSet = CharSet.Ansi)]
| public static extern int getDeviceProductString(
| [In, Out] IntPtr deviceHandle,
| [In, Out] ref StringBuilder Product,
| [In, Out] ref byte Length,
| [In] bool ConvertToASCII);
|
| [DllImport(CP210xManu, EntryPoint = "CP210x_GetDeviceSerialNumber",
| CharSet = CharSet.Ansi)]
| public static extern int getDeviceSerialNumber(
| [In, Out] IntPtr deviceHandle,
| [In, Out] ref StringBuilder Product,
| [In, Out] ref byte Length,
| [In, Out] bool ConvertToASCII);
|
| [DllImport(CP210xManu, EntryPoint = "CP210x_GetDeviceVid")]
| public static extern int getDeviceVid(
| [In, Out] IntPtr deviceHandle,
| [In, Out] ref ushort Vid);
|
| [DllImport(CP210xManu, EntryPoint = "CP210x_GetDevicePid")]
| public static extern int getDevicePid(
| [In, Out] IntPtr deviceHandle,
| [In, Out] ref ushort Pid);
| }




| here is the function durring debug
void loadSettings(){
IntPtr siRef = IntPtr.Zero;
int result = 0;
uint numDevice = 0;
result = DeviceWrappers.CSepSIChipWrap.getNumDevices(ref numDevice);
//result = 0 after execute
result = DeviceWrappers.CSepSIChipWrap.open(0, siRef); //result =1
siRef = 0 after execute ushort pid = 0;
result = DeviceWrappers.CSepSIChipWrap.getDevicePid(siRef, ref pid);
//result = 3 after execute "Device IO Failed"
//pid still equals zero at this point and should be some hex value like
0x10c4
//lbDevicePID is a .net text label on a user control
this.lbDevicePID.Text = pid.ToString();
}

this asures me that the handle is the problem in the statement
getDevicePid because the same error is reported in both circuimstances.

Device Manager reports the device as being there.

It also seems that "ref IntPtr var" is more correct than "IntPtr var"
 
W

Willy Denoyette [MVP]

|I tested that before with no, luck.
|
| So, just to be sure i made the appropriate changes and tried it agian.
| | class CSepSIChipWrap
|| {
|| private const string CP210xManu = "CP210xManufacturing.dll";
||
|| [DllImport(CP210xManu, EntryPoint = "CP210x_GetNumDevices")]
|| public static extern int getNumDevices(
|| [In, Out] ref UInt32 deviceNumb);
||
|| [DllImport(CP210xManu, EntryPoint = "CP210x_Open")]
|| public static extern int open(
|| [In] UInt32 deviceNumb,
|| [In, Out] IntPtr deviceHandle);
||
|| [DllImport(CP210xManu, EntryPoint = "CP210x_Close")]
|| public static extern int close(
|| [In, Out] IntPtr deviceHandle);
||
|| [DllImport(CP210xManu, EntryPoint = "CP210x_GetDeviceProductString",
|| CharSet = CharSet.Ansi)]
|| public static extern int getDeviceProductString(
|| [In, Out] IntPtr deviceHandle,
|| [In, Out] ref StringBuilder Product,
|| [In, Out] ref byte Length,
|| [In] bool ConvertToASCII);
||
|| [DllImport(CP210xManu, EntryPoint = "CP210x_GetDeviceSerialNumber",
|| CharSet = CharSet.Ansi)]
|| public static extern int getDeviceSerialNumber(
|| [In, Out] IntPtr deviceHandle,
|| [In, Out] ref StringBuilder Product,
|| [In, Out] ref byte Length,
|| [In, Out] bool ConvertToASCII);
||
|| [DllImport(CP210xManu, EntryPoint = "CP210x_GetDeviceVid")]
|| public static extern int getDeviceVid(
|| [In, Out] IntPtr deviceHandle,
|| [In, Out] ref ushort Vid);
||
|| [DllImport(CP210xManu, EntryPoint = "CP210x_GetDevicePid")]
|| public static extern int getDevicePid(
|| [In, Out] IntPtr deviceHandle,
|| [In, Out] ref ushort Pid);
|| }
|
|
|
|
| | here is the function durring debug
| void loadSettings(){
| IntPtr siRef = IntPtr.Zero;
| int result = 0;
| uint numDevice = 0;
| result = DeviceWrappers.CSepSIChipWrap.getNumDevices(ref numDevice);
| //result = 0 after execute
| result = DeviceWrappers.CSepSIChipWrap.open(0, siRef); //result =1
| siRef = 0 after execute ushort pid = 0;
| result = DeviceWrappers.CSepSIChipWrap.getDevicePid(siRef, ref pid);
| //result = 3 after execute "Device IO Failed"
| //pid still equals zero at this point and should be some hex value like
| 0x10c4
| //lbDevicePID is a .net text label on a user control
| this.lbDevicePID.Text = pid.ToString();
| }
|
| this asures me that the handle is the problem in the statement
| getDevicePid because the same error is reported in both circuimstances.
|
| Device Manager reports the device as being there.
|
| It also seems that "ref IntPtr var" is more correct than "IntPtr var"

You got it wrong, the openfunction takes a pointer to a handle, the
getDevicePid function takes a handle.

So:
open(0, siRef); // this returns 1 which means invalid handle.
should be
open(0, ref siRef);

while
getDevicePid(siRef, ref pid);
is OK.

Willy.

the Willy.
 
J

justin.kruger

thank you so very much, that was it.

Its amazing how the simple things tend to be the really hard ones.
 
W

Willy Denoyette [MVP]

| thank you so very much, that was it.
|
| Its amazing how the simple things tend to be the really hard ones.
|
Very true :).

Willy.
 

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