2
Reply

Unsafe code, pointer to LPVOID, LPSTR

Ask a question
Issam Hijazi

Issam Hijazi

13y
2.3k
1

Hi,

I have this DLL which I'm trying to use in my managed code in order to access certain device API. In the documentation, I should have a "struct" and pass it in the DLL methods as a parameter for both passing parameters and getting results. In C++, it looks like this:

typedef struct _MCPBUS   {   DWORD  dwOperAttribute ; // operation attribute   DWORD  dwApplicationID ; // application ID   DWORD  dwCommandID   ; // command ID   DWORD  dwResultCode   ; // command result code   LPSTR  lpszPropertyName ; // pointer to property name   DWORD  dwPropertyID   ; // property ID   DWORD  dwPropertyType  ; // property type   LPVOID lpInBuffer    ; // pointer to input buffer   DWORD  dwInBufferLen  ; // length of data in input buffer   LPVOID lpOutBuffer   ; // pointer to output buffer   DWORD  dwOutBufferSize ; // output buffer size   DWORD  dwResponseLen  ; // length of response in output buffer   DWORD  dwTimeout    ; // notification timeout value   DWORD  dwContext    ; // device enumeration context   } MCPBUS, *PMCPBUS; 


I "tried" to translate that into C# and I came up with this:

  public unsafe class _MCPBUS   {     public uint dwOperAttribute; // operation attribute     public uint dwApplicationID; // application ID     public uint dwCommandID; // command ID     public uint dwResultCode; // command result code     public uint* lpszPropertyName; // pointer to property name     public uint dwPropertyID; // property IDk     public uint dwPropertyType; // property type     public byte*[] lpInBuffer; // pointer to input buffer     public uint dwInBufferLen; // length of data in input buffer     public byte*[] lpOutBuffer; // pointer to output buffer     public uint dwOutBufferSize; // output buffer size     public uint dwResponseLen; // length of response in output buffer     public uint dwTimeout; // notification timeout value     public uint dwContext; // device enumeration context   } 


And I DO believe is VERY wrong. Mainly, I'm suspecious about lpInBuffer,lpOutBuffer and lpszPropertyName.

Question 1: Is my declaration in C# correct? If not, what is the correct one?

 

Let's get to the next point. Now, in the DLL there is a method called "McpEnum", its prototype goes like this:

DWORD WINAPI McpEnum (MCPBUS *pMCPBUS); 

Input parameters for McpEnum from struct are dwContext, lpOutBuffer and dwOutBufferSize. (Check the struct in the beginning).

Output result for McpEnum from same struct is dwContext, lpOutBuffer and dwResponseLen.

I'm calling the mothod in C# like the following:

[DllImport("MCPapi.dll")] public static extern uint McpEnum(_MCPBUS pMCPBUS);

Quesion 2: How do I call it probably?

I know (for some reason) that the way I'm calling the method is wrong, since there a pointer. Also, how should I be passing the struct? Yes, I need to define it, and then fill the 3 required parameters, but I'm not sure also how to fill those three (dwContext, lpOutBuffer and dwOutBufferSize).

Question 3: There are many other methods, but I want to list only one more (from Document specs), and have your feedback on how it should be implemented in C#:

McpOpen

This function is used to open the communication channel and establish communications with an MCP device. Use McpClose to close the channel.

DWORD McpOpen( LPSTR lpDeviceName, PHANDLE hpDevice );

Parameters:

lpDeviceName
Pointer to a null terminated string which specifies the logical device name of the MCP device to which communications is to be established. This name could be a hard coded device name, a name obtained from the registry, or other configuration data, or more likely, a name returned from the McpEnum function.

hpDevice
Pointer to storage area to receive the open handle to the specified device (communications resource). This handle is used on subsequent calls to functions requiring communications with the MCP device. If the function fails, the value of hpDevice is not modified.

 

That's it, I'd highly appreciate any feedback.

Thank you.


Answers (2)