一:
struct MAPI_DATA_SET_TX_FREQUENCY_CMD
{
    /** Present optional arguments. */
    unsigned int Options[10];
    
    /** AutoSet value. */
    unsigned char AutoSet;
    
    /** CenterFrequency value. */
    unsigned short CenterFrequency;
    
    /** InventoryFilterAPattern value. */
    unsigned char * InventoryFilterAPattern;
    
    /** HaltFilterAMask value. */
    unsigned short * HaltFilterAMask;    /** Data */
    void * Data;
   
    /** Handle to handle */
    Handle hFile;    /** pointer to a Window*/
    HWND hDlgMain;    
};

解决方案 »

  1.   

    C#里也有结构体啊..
    public struct test
    {
       string oid;
       string value;
    }
      

  2.   

    楼上的说得没错C#也有struct
    只不过HWND和handle就比较麻烦了
      

  3.   

    liujia_0421()正解
    Handle 和HWND在.net里都有对应的类的
      

  4.   

    TO:只不过HWND和handle就比较麻烦了C#里也有类似的,可以查下MSDN..就是真的没有,也可以换别的类型,可以灵活一点..
      

  5.   

    是啊,C#中有结构体,可能我的表述不是很清楚,其实我就是想请教大家如何在C#中用结构体来重新定义与C++中的该结构体相同的结构体,因为我要调用非托管dll中的函数!谢谢各位了!!!
      

  6.   

    另外我有一个非托管的Dll函数GetData(),其返回值就是这样一个结构,如下:
    MAPI_DATA_SET_TX_FREQUENCY_CMD GetData();
    当调用该函数成功(在C#中使用[Dllimport]进行引入了)后,其成员(C#中是不是叫字段?) Data是void *(当然在C#结构体中我们可能用IntPtr来代替该指针),那么在C#中如何将该指针转换为结构呢?是不是必须使用如下unsafe方法才能提取其中的细节数据?有没有不用unsafe的方法?
    MAPI_DATA_SET_TX_FREQUENCY_CMD mapiData = GetData();
    unsafe
    {
        MyStruct *pMyStruct = (MyStruct *)mapiData.Data;
        pMyStruct->......
    }
      

  7.   

    不是一样的吗对应C#中的结构体结构内可以是string 类型或者任意你的 class类型指针用ref
      

  8.   

    其实我就是不太清楚如何将C++中的结构体转换为C#的,主要是封送数据类型不是很清楚!
    public struct MAPI_DATA_SET_TX_FREQUENCY_CMD
    {
        /** Present optional arguments. */
        unsigned int Options[10];// 这里不知如何处理?
        
        /** AutoSet value. */
        // unsigned char AutoSet;
        byte AutoSet;
        
        /** CenterFrequency value. */
        // unsigned short CenterFrequency;
        ushort CenterFrequency;
        
        /** InventoryFilterAPattern value. */
        unsigned char * InventoryFilterAPattern;// 这里不知如何处理?
        
        /** HaltFilterAMask value. */
        unsigned short * HaltFilterAMask;// 这里不知如何处理?    /** Data */
        // void * Data;
        IntPtr Data;// 是否可以这样?
       
        /** Handle to handle */
        Handle hFile;// 这里不知如何处理?    /** pointer to a Window*/
        HWND hDlgMain;// 这里不知如何处理?
    };
      

  9.   

    try
    [StructLayout(LayoutKind.Sequential)]
    struct MAPI_DATA_SET_TX_FREQUENCY_CMD
    {
        /** Present optional arguments. */
        uint Options[10];
        
        /** AutoSet value. */
        byte AutoSet;
        
        /** CenterFrequency value. */
        ushort CenterFrequency;
        
        /** InventoryFilterAPattern value. */
        string  InventoryFilterAPattern;
        
        /** HaltFilterAMask value. */
        ref ushort  HaltFilterAMask;    /** Data */
        System.IntPtr Data;
       
        /** Handle to handle */
        System.IntPtr hFile;    /** pointer to a Window*/
        System.IntPtr hDlgMain;    
    }
      

  10.   

    基本差不多,不过指针类型的就不好办了
    char *可以理解为一个数组型的,用string就行了
      

  11.   

    试一下
    [StructLayout(LayoutKind.Sequential)]
            public struct MAPI_DATA_SET_TX_FREQUENCY_CMD {
                
                [MarshalAs(UnmanagedType.ByValArray, SizeConst = 10)]
                public uint[] Options;
                /** AutoSet value. */
                public byte AutoSet;
                
                /** CenterFrequency value. */
                public ushort CenterFrequency;            /** InventoryFilterAPattern value. */
                public IntPtr InventoryFilterAPattern;            /** HaltFilterAMask value. */
                public IntPtr HaltFilterAMask;            /** Data */
                public IntPtr Data;            /** Handle to handle */
                public IntPtr hFile;            /** pointer to a Window*/
                public IntPtr hDlgMain; 
            }
      

  12.   

    To:hdt(倦怠)
    问题1:uint Options[10];//这种声明是不行的,C#中声明数组,然后我把它改成:uint[10] Options;此时出现下述错误:
    错误 1 不能在变量声明中指定数组大小(请尝试使用“new”表达式初始化)
    问题2:ref ushort  HaltFilterAMask;// 这种定义导致如下错误
    错误 2 类、结构或接口成员声明中的标记“ref”无效
      

  13.   

    C++里的结构体在C#中一般用类表示,可以在调用函数外定义一个类,然后在调用函数处声明这个类的实例即可。
    C++中的HANDLE在C#中有IntPtr表示。
    另外,在调用C++的函数时,可以在参数前用[MarshalAs(UnmanagedType.类型)]指定托管/非托管对应关系。
      

  14.   

    To:ys119(mars)
    按照你的帮助,我做了如下示例:编译可以通过,但是执行的时候出现异常:nullReferenceException,提示如下:未将对象引用设置到对象的实例。我的例程代码如下:
    namespace ConsoleApplication1
    {
        class Program
        {
            static void Main(string[] args)
            {
                MAPI_DATA_SET_TX_FREQUENCY_CMD myStruct = new MAPI_DATA_SET_TX_FREQUENCY_CMD();
                myStruct.Options[0] = 10;// 执行到这里出现异常
                myStruct.Options[1] = 10;
            }
            [StructLayout(LayoutKind.Sequential)]
            public struct MAPI_DATA_SET_TX_FREQUENCY_CMD
            {
                [MarshalAs(UnmanagedType.ByValArray, SizeConst = 10)]
                public uint[] Options;
                /** AutoSet value. */
                public byte AutoSet;
                
                /** CenterFrequency value. */
                public ushort CenterFrequency;            /** InventoryFilterAPattern value. */
                public IntPtr InventoryFilterAPattern;            /** HaltFilterAMask value. */
                public IntPtr HaltFilterAMask;            /** Data */
                public IntPtr Data;            /** Handle to handle */
                public IntPtr hFile;            /** pointer to a Window*/
                public IntPtr hDlgMain;
            }
        }
    }
      

  15.   

    但是如果我将Main函数改成这样就可以了:
            static void Main(string[] args)
            {
                MAPI_DATA_SET_TX_FREQUENCY_CMD myStruct = new MAPI_DATA_SET_TX_FREQUENCY_CMD();
                myStruct.Options = new uint[10];// 分配空间
                myStruct.Options[1] = 10;
            }
      

  16.   

    To nany99():
    “C++里的结构体在C#中一般用类表示,可以在调用函数外定义一个类,然后在调用函数处声明这个类的实例即可。”--------C++中都是声明为struct的,在C#中如果改为类,这样传到非托管的C++动态库(dll)的函数中行不行?希望给一个确定的答案!谢谢!!!
      

  17.   

    如果与dll交互只能定义为struct,绝对不可以定义为class
      

  18.   

    如果是api函数参数的转换的话可以按照下面的方法:
        1、数值型直接用对应的就可。(DWORD -> int , WORD -> Int16)  2、API中字符串指针类型 -> .net中string  3、API中句柄 (dWord) -> .net中IntPtr  4、API中结构 -> .net中结构或者类。注意这种情况下,要先用StructLayout特性限定声明结构或类
      

  19.   

    To SmallMummy(笑看人生) :
        字符串指针类型-> .net中string
        其它类型的指针呢?如unsigned short * ->.Net中...???
      

  20.   

    To eeixy2000:
    似乎是
    int param* ->
    [in, out] int[] param我没试过,你看看行不
      

  21.   

    to eeixy2000(老顽童) :
        To nany99():
        “C++里的结构体在C#中一般用类表示,可以在调用函数外定义一个类,然后在调用函数处声明       这个类的实例即可。”-- ------C++中都是声明为struct的,在C#中如果改为类,这样传到非托管的C++动态库(dll)的函数中行不行?希望给一个确定的答案!谢谢!!!
    ==============================
    我原来试过调用时用struct和class都可以,但是我通常都用struct,因为C#中struct的行为和C++中的class和struct比较类似。到时候用起来比较好控制。to eeixy2000(老顽童) :
        To:ys119(mars)
        按照你的帮助,我做了如下示例:编译可以通过,但是执行的时候出现异常:nullReferenceException,提示如下:未将对象引用设置到对象的实例。
    ===================================
    我以为你的这个结构是调用非托管代码后得到的,所以没有写对这个struct内部成员进行初始化的东西。如需要你自己可以设置初始值。如:[MarshalAs(UnmanagedType.ByValArray, SizeConst = 10)]
    public uint[] Options = new uint[10];
      

  22.   

    to eeixy2000(老顽童) :
    To SmallMummy(笑看人生) :
    字符串指针类型-> .net中string
    其它类型的指针呢?如unsigned short * ->.Net中...???
    ========================================
    这些指针都可以用IntPtr类型来代替,到时如果要使用数据时通过Marshal类的一些方法可以进行操作。之所以用string来替代字符串指针类型,是因为应用上比较方便,其实用Intptr一样可以,但是需要再转换,就麻烦了。
      

  23.   

    to SmallMummy(笑看人生) :
    3、API中句柄 (dWord) -> .net中IntPtr
    =========================
    API中句柄 DWORD -〉 UIntPtr
      

  24.   

    To efijki(YD) :
        对你的提法很感兴趣,能否详细一点?
        事实上我也不想用指针,因为要从函数中把数据返回来,这时候就要用到将指针转换为结构或其它的指针,这就需要设置unsafe代码段来进行,这是不好的,所以请讲详细一点,谢谢!
      

  25.   

    To efijki(YD) :
        例如当从C++托管函数中返回MAPI_DATA_SET_TX_FREQUENCY_CMD结构类数据时,其数据成员Data(void * Data;)对应另一个结构OtherStruct,我就需要将该(void *Data)(C#中可能定义为IntPtr Data)-->OtherStruct*(又是指针),这就需要声明unsafe代码段!请问你如何解决这个问题,谢谢!
      

  26.   

    to eeixy2000(老顽童) :
    =============================================
    To efijki(YD) :
    例如当从C++托管函数中返回MAPI_DATA_SET_TX_FREQUENCY_CMD结构类数据时,其数据成员Data(void * Data;)对应另一个结构OtherStruct,我就需要将该(void *Data)(C#中可能定义为IntPtr Data)-->OtherStruct*(又是指针),这就需要声明unsafe代码段!请问你如何解决这个问题,谢谢!
    ================================================
    这个问题,你先定义一个C#中的struct OtherStruct,然后Data(void * Data);-->Data(ref OtherStruct Data);
      

  27.   

    Char * 相当于 byte []
    我实验过的
      

  28.   

    To ys119(mars):
        能否把C#中的定义和调用具体写下来,没有太看明白你的意思!谢啦!!!
      

  29.   

    比如你在C++中一个方法是void f(A* para);其中A是一个C++中的struct,那么你在C#中需要这样申明这个函数(注意现在C#中定义一个结构A,和C++中一致):
    [DllImport(dllName, EntryPoint = "f")]
    public static extern void f(ref A para);
      

  30.   

    To ys119(mars):
        如果该para有一个IntPtr的成员data,其实际对应某结构(设为MyCsharpStructB)的指针,那么在C#中如何将该data成员转换为MyStructA?看看我这样作是否妥当?
       ...
       MyCsharpStructA para = new MyCsharpStructA();
       f(ref para);
       unsafe
       {
           MyCsharpStructB * = (MyCsharpStructB *)para.data;
           // Other operation
       }
    这样就必须用指针了,有没有不用指针的方法?
      

  31.   

    不需要用unsafe啊,你可以这样:
    IntPrt pt = para.data; //这个在结构里面就定义为IntPtr
    假如你要使用那个结构的对象:
    MyCsharpStructB structB = (MyCsharpStructB) Marshal.PtrToStructure(pt);
      

  32.   

    经过这几天的测试和各位的帮忙,问题基本解决!下面进行总结:
    C#定义该结构可以如下:
    [StructLayout(LayoutKind.Sequential)]
    struct MAPI_DATA_SET_TX_FREQUENCY_CMD
    {
        [MarshalAs(UnmanagedType.ByValArray, SizeConst = 10)]
        /** Present optional arguments. */
        uint[] Options;
        
        /** AutoSet value. */
        byte AutoSet;
        
        /** CenterFrequency value. */
        ushort CenterFrequency;
        
        /** InventoryFilterAPattern value. */
        string InventoryFilterAPattern;
        
        /** HaltFilterAMask value. */
        IntPtr HaltFilterAMask;    /** Data */
        IntPtr Data;
       
        /** Handle to handle */
        IntPtr hFile;    /** pointer to a Window*/
        IntPtr hDlgMain;    
    };调用时,可以通过应用传递ref;
    返回时可以通过Marshal.PtrToStructure将其中的指针转换为结构,或者如果该指针对应的不是结构体,可以通过Marshal.Copy将数据拷贝到托管变量中!
    谢谢各位的帮忙!