从c++到c# . net紧凑框架结构转换中的问题

本文关键字:转换 框架结构 问题 c++ net | 更新日期: 2023-09-27 17:53:44

我正在将c/c++结构转换为c#标准。

C/c++结构:

 typedef struct _sta_conn_info{
STA_CONNECT_STATE               connect_state;//Enum
STA_ASSOC_STATE                 assoc_state;//Enum
unsigned char               bssid[6];
unsigned char               ssid[34];   
unsigned long               channel;
enum mode               mode;//Enum
unsigned long               signalStrength; 
    unsigned long               noiseLevel;     
STA_AUTH_ALG                    auth_alg;//enum
STA_ENCRYPT_ALG                 encrypt_alg;//enum  
}STA_CONN_INFO;

 typedef struct _NDISUIO_QUERY_OID
         {
           NDIS_OID        Oid;
           PTCHAR          ptcDeviceName;  
           UCHAR           Data[sizeof(ULONG)];
         } NDISUIO_QUERY_OID, *PNDISUIO_QUERY_OID;

各自的c#结构:

     [StructLayout(LayoutKind.Sequential, CharSet = CharSet.Unicode)]
    public struct _sta_conn_info
    {
        public _sta_connect_state       connect_state;      
        public _sta_assoc_state         assoc_state; 
            [MarshalAs(UnmanagedType.ByValArray,SizeConst = 6)]
        public char[]               bssid ;//= new char[6];
            [MarshalAs(UnmanagedType.ByValArray,SizeConst = 34)]
        public char[]               ssid ;//= new char[34]  
        public uint         channel;
        public mode             mode;
        public uint             signalStrength; 
            public uint             noiseLevel;     
        public _sta_auth_alg            auth_alg;
        public _sta_encrypt_alg         encrypt_alg;
         }
    QUERY STRUCT:   
    [StructLayout(LayoutKind.Sequential, CharSet = CharSet.Unicode)]
    public struct _NDISUIO_QUERY_OID
    {
        public uint        Oid;
        [MarshalAs(UnmanagedType.LPWStr)]
        public string          ptcDeviceName;
        public byte[] Data;
    };

我使用这个>>>引用

转换数据类型

Marshal.SizeOf()在WIN CE中工作。我测试过了。

如果我的结构转换是好的,那么肯定Marshal.SizeOf()将工作,以获得结构的大小,但它抛出异常,并返回error code 87在DeviceIoControl() API。

谁能澄清我的转换,让我知道如果我做错了什么。

从c++到c# . net紧凑框架结构转换中的问题

对于bssidssid, c++声明如下:

unsigned char bssid[6];
unsigned char ssid[34];   

现在,unsigned char是一个单字节,通常用于字节数组而不是文本。所以c#应该是:

[MarshalAs(UnmanagedType.ByValArray,SizeConst = 6)]
public byte[] bssid ;//= new byte[6];
[MarshalAs(UnmanagedType.ByValArray,SizeConst = 34)]
public byte[] ssid ;//= new byte[34]  

你在c#中使用char是不正确的,因为char在c#中是两个字节宽的。

_NDISUIO_QUERY_OID

[MarshalAs(UnmanagedType.ByValTStr, SizeConst = sizeof(uint))]
public byte[] Data;

我认为你需要使用ByValArray而不是ByValTStr。但正如我们在你最近的许多问题中所讨论的那样,这个成员的确切含义并不清楚。它真的是一个固定长度的字节数组,还是一个可变长度的缓冲区?你有可用的c++示例代码吗?那将一劳永逸地解决这场争论。


好的,从头文件nuiouser.h我有这个:

//
//  Structure to go with IOCTL_NDISUIO_QUERY_OID_VALUE.
//  The Data part is of variable length, determined by
//  the input buffer length passed to DeviceIoControl.
//
typedef struct _NDISUIO_QUERY_OID
{
    NDIS_OID        Oid;
#ifdef UNDER_CE
    //
    //  In CE land app is allowed to query without having to do
    //  IOCTL_NDISUIO_OPEN_DEVICE
    //  Hence the device name to query argument needed..
    //  For app that does IOCTL_NDISUIO_OPEN_DEVICE this argument
    //  is then not necessary..
    //
    PTCHAR          ptcDeviceName;  
#endif
    UCHAR           Data[sizeof(ULONG)];
} NDISUIO_QUERY_OID, *PNDISUIO_QUERY_OID;

告诉你Data是可变长度的。恐怕您需要用AllocHGlobal来分配结构体,并手工完成所有的编组。