http://dongtingyueh.blog.163.com/blog/static/4619453201302392757923/你的问题很简单,看下自己弄明白了,永远都不用求人,所以我就不给你代码了。

解决方案 »

  1.   

    Platform invoke中,有很多细节需要注意,比较麻烦
    1.c中的struct和c#中的struct对应
       定义struct的时候用StructLayoutAttribute控制结构体的数据字段在托管内存中的物理布局,
    即类或结构需要按某种方式排列。例如
       
            [StructLayout(LayoutKind.Sequential, CharSet = CharSet.Ansi, Pack = 1)]
        
    2. c的基本类型和C#类型一一对应
       string需要特殊声明,例如
      
           [MarshalAs(UnmanagedType.ByValTStr, SizeConst = 260)]
            public string LogFilePath;
      
       如果传入的是基本类型指针,需要传值出来的,加上ref或者out
    3. 结构体指针在C#中用定义的结构体就可以
      
         public struct SConfig
        {
           public SAdvanceConfig m_Cfg;  //SAdvanceConfig为结构体
        }
      
    4. 在DLLImport的时候,需要显式声明想关属性  [DllImport("mydll_x64", EntryPoint = "MyTest", CharSet = CharSet.Ansi, CallingConvention = CallingConvention.StdCall)]
      

  2.   

    内个 我就想用这个函数
    unsigned long PDC_DetectDevice(
        unsigned long nInterfaceCode
        unsigned long *pDetectNo
        unsigned long nDetectNum
        unsigned long nDetectParam
        PPDC_DETECT_NUM_INFO pDetectNumInfo //这个是指针啊! 结构体指针啊 !
        unsigned long *pErrorCode
    )这个结构体地址&DetectNumInfo在C#里怎么弄啊
      

  3.   

    内个 我就想用这个函数
    unsigned long PDC_DetectDevice(
        unsigned long nInterfaceCode
        unsigned long *pDetectNo
        unsigned long nDetectNum
        unsigned long nDetectParam
        PPDC_DETECT_NUM_INFO pDetectNumInfo //这个是指针啊! 结构体指针啊 !
        unsigned long *pErrorCode
    )这个结构体地址&DetectNumInfo在C#里怎么弄啊
    对应用结构体就行了,本质就是传个地址进去
    但也有要求,
    就是定义的这个结构体在托管内存中的物理布局要和
    c dll要求的一致
      

  4.   


    我就是想知道初始化一个结构体之后 怎么能获得他的地址指针 因为这个DLL文件里的函数是那么定义的哈
    直接应用结构体就会出这个
    “System.AccessViolationException”类型的第一次机会异常在 CCD控制台应用程序2.exe 中发生
    “System.AccessViolationException”类型的未经处理的异常在 CCD控制台应用程序2.exe 中发生 
    其他信息: 尝试读取或写入受保护的内存。这通常指示其他内存已损坏
    内个 我就想用这个函数
    unsigned long PDC_DetectDevice(
        unsigned long nInterfaceCode
        unsigned long *pDetectNo
        unsigned long nDetectNum
        unsigned long nDetectParam
        PPDC_DETECT_NUM_INFO pDetectNumInfo //这个是指针啊! 结构体指针啊 !
        unsigned long *pErrorCode
    )这个结构体地址&DetectNumInfo在C#里怎么弄啊
    对应用结构体就行了,本质就是传个地址进去
    但也有要求,
    就是定义的这个结构体在托管内存中的物理布局要和
    c dll要求的一致
      

  5.   

    C#定义的结构体和api代码贴出来看看
      

  6.   

    内个 我就想用这个函数
    unsigned long PDC_DetectDevice(
        unsigned long nInterfaceCode
        unsigned long *pDetectNo
        unsigned long nDetectNum
        unsigned long nDetectParam
        PPDC_DETECT_NUM_INFO pDetectNumInfo //这个是指针啊! 结构体指针啊 !
        unsigned long *pErrorCode
    )这个结构体地址&DetectNumInfo在C#里怎么弄啊
    使用out引用传出就行。out ]PPDC_DETECT_NUM_INFO pDetectNumInfo
      

  7.   

    使用 In,Out 属性来修饰这个参数。
    同时定义 C# 版本的结构,使用 StructLayOut 修饰结构。
    结构中的数组,使用 UnmanagedType.LPArray 和 SizeConst 修饰。
      

  8.   

    两个结构体     
       [StructLayoutAttribute(LayoutKind.Sequential)]
            public struct PDC_DETECT_INFO
            {
                /// unsigned int
                public uint m_nDeviceCode;
                /// unsigned int
                public uint m_nTmpDeviceNo;
                /// unsigned int
                public uint m_nInterfaceCode;
            }
            [StructLayoutAttribute(LayoutKind.Sequential)]
            public unsafe struct PDC_DETECT_NUM_INFO
            {
                public uint m_nDeviceNum;
                [MarshalAsAttribute(UnmanagedType.ByValArray, SizeConst = PDC_MAX_DEVICE)]
                PDC_DETECT_INFO[] m_DetectInfo ;
            }
      

  9.   

            [DllImport("PDCLIB.dll")]
            public  unsafe static extern uint PDC_DetectDevice(
            uint nInterfaceCode,
            uint pDetectNo,
            uint nDetectNum,
            uint nDetectParam,
            PDC_DETECT_NUM_INFO pDetectNumInfo,
            uint *pErrorCode
            );
      

  10.   

    内个 我就想用这个函数
    unsigned long PDC_DetectDevice(
        unsigned long nInterfaceCode
        unsigned long *pDetectNo
        unsigned long nDetectNum
        unsigned long nDetectParam
        PPDC_DETECT_NUM_INFO pDetectNumInfo //这个是指针啊! 结构体指针啊 !
        unsigned long *pErrorCode
    )这个结构体地址&DetectNumInfo在C#里怎么弄啊
    使用out引用传出就行。out ]PPDC_DETECT_NUM_INFO pDetectNumInfo在结构体指针定义前加out么?我试了 不好使哈 您给看看楼上那两个
      

  11.   

    lz看帖不仔细,建议重读下回帖public static extern int GetAttrArray(..., [Out] MyAttr[] pAttrArray);其中,MyAttr为自定义结构体
      

  12.   

            public  unsafe static extern uint PDC_DetectDevice(
            uint nInterfaceCode,
            uint pDetectNo,
            uint nDetectNum,
            uint nDetectParam,
            out  PDC_DETECT_NUM_INFO[] pDetectNumInfo,
            uint *pErrorCode
            );你是说这样的么?
      

  13.   

            public  unsafe static extern uint PDC_DetectDevice(
            uint nInterfaceCode,
            uint pDetectNo,
            uint nDetectNum,
            uint nDetectParam,
            out  PDC_DETECT_NUM_INFO pDetectNumInfo,
            uint *pErrorCode
            );不过怎么加都不好使
                    
     nRet = PDC_DetectDevice(PDC_INTTYPE_G_ETHER,    /* Gigabit-Ether I/F */
                                             IPList[0],                 /* IP address */
                                             1,                      /* Maximum number of searched devices */
                                             PDC_DETECT_NORMAL,      /* Specifies an IP address explicitly */
                                             out DetectNumInfo,
                                             &nErrorCode);
    C++
    的调用例子是下面这样的
    unsigned long nRet;
    unsigned long nDeviceNo;                /* Device number */
    unsigned long nErrorCode;
    PDC_DETECT_NUM_INFO DetectNumInfo;      /* Search result */
    unsigned long IPList[PDC_MAX_DEVICE];   /* IP address to be searched */
    IPList[0] = 0xC0A8000A;                 /* 192.168.0.10 */nRet = PDC_DetectDevice(PDC_INTTYPE_G_ETHER, /* Gigabit-Ether I/F */
                            IPList,              /* IP address */
                            1,                   /* Maximum number of searched devices */
                            PDC_DETECT_NORMAL,   /* Specifies an IP address explicitly */
                            &DetectNumInfo,
                            &nErrorCode);if (nRet == PDC_FAILED) {
        printf("PDC_DetectDevice Error %d\n", nErrorCode);
        return;
      

  14.   

    [DllImport(dllPath, EntryPoint = "PDC_DetectDevice", CallingConvention = CallingConvention.Cdecl)]
    private static extern UInt32 PDC_DetectDevice(UInt32 nInterfaceCode, UInt32[] pDetectNo, UInt32 nDetectNum, UInt32 nDetectParam, out PDC_DETECT_NUM_INFO DetectNumInfo, out UInt32 pErrorCode);
    public static DETECT_INFO[] DetectDevice(uint interfaceCode, uint[] detectNo, uint detectNum, uint detectParam)
    {
    UInt32 errorCode;
    PDC_DETECT_NUM_INFO detectNumInfo ;
    PDC_DetectDevice(interfaceCode, detectNo, detectNum, detectParam, out detectNumInfo, out errorCode);
    return Enumerable.Range(0,(int) detectNumInfo.m_nDeviceNum)
    .Select(i => new DETECT_INFO
    {
    DeviceCode = detectNumInfo.m_DetectInfo[i].m_nDeviceCode,
    InterfaceCode = detectNumInfo.m_DetectInfo[i].m_nInterfaceCode,
    TmpDeviceNo = detectNumInfo.m_DetectInfo[i].m_nTmpDeviceNo
    })
    .ToArray();
    } do
    {
    var info = NativeImport.DetectDevice(1, new uint[] { 0xC0A8000A }, 1, 0);
    System.Diagnostics.Debug.WriteLine(string.Join("\r\n", info.Select(i=>string.Format("{0:X8}, {1:X8}, {2:X8};", i.DeviceCode, i.InterfaceCode, i.TmpDeviceNo))));
    } while (false);
      

  15.   

    class NativeImport
    {
    [StructLayout(LayoutKind.Sequential)]
    public struct PDC_DETECT_INFO
    {
    public UInt32 m_nDeviceCode;
    public UInt32 m_nTmpDeviceNo;
    public UInt32 m_nInterfaceCode;
    };
    [StructLayout(LayoutKind.Sequential)]
    public struct PDC_DETECT_NUM_INFO
    {
    public UInt32 m_nDeviceNum;
    [MarshalAs(UnmanagedType.ByValArray, SizeConst = 16)]
    public PDC_DETECT_INFO[] m_DetectInfo;
    };
    public class DETECT_INFO
    {
    public uint DeviceCode;
    public uint TmpDeviceNo;
    public uint InterfaceCode;
    };
    }