本帖最后由 Li_Huiyi 于 2010-09-30 11:18:20 编辑

解决方案 »

  1.   

    DWORD 对应 C#的 long 吧
      

  2.   

    加一个字节对齐试试
    [StructLayout(LayoutKind.Sequential, CharSet = CharSet.Ansi,Pack=1)]
      

  3.   

    实在不行,你就一个一个拷贝吧。
    指针已经得到了,只要拷贝制定大小就行了。
    int dwSize = ConvertInt(serverInfo);
    dwServerFlag = ConvertInt(serverInfo);
      

  4.   


    试了,没用。
    调用的函数
    re = JBNV_DLLFuction.JBNV_GetServerInfo(hServer, ref serverInfo);
    两个参数,第一个参数是上一个函数(同一个dll里面的函数)返回的视频服务器句柄,所以这个参数应该不会有问题。函数返回的结果显示参数不正确,我就判断是第二个参数传的不对。
    我想可能是对这两个成员的类型转化有问题,到底该怎么转呢?
    BYTE bServerSerial[48]; //服务器序列号,具有唯一标识功能
    BYTE byMACAddr[6]; //服务器的物理地址我一开始参照MSDN上这样的一个例子:// 传递到该函数的初始结构包含以下元素:
    typedef struct _OSVERSIONINFO

      DWORD dwOSVersionInfoSize; 
      DWORD dwMajorVersion; 
      DWORD dwMinorVersion; 
      DWORD dwBuildNumber; 
      DWORD dwPlatformId; 
      TCHAR szCSDVersion[ 128 ]; 
    } OSVERSIONINFO;
    // 函数原型:
    BOOL GetVersionEx(LPOSVERSIONINFO lpVersionInfo);
    // C#中的定义
    [ StructLayout( LayoutKind.Sequential )]  
    public struct OSVersionInfo2 
    {
        public int OSVersionInfoSize;
        …
       [ MarshalAs( UnmanagedType.ByValTStr, SizeConst=128 )]
        public String versionString;
    }public class LibWrap 
    {
       [ DllImport( "kernel32" )]
       public static extern bool GetVersionEx( [In, Out] OSVersionInfo osvi );   [ DllImport( "kernel32", EntryPoint="GetVersionEx" )] 
       public static extern bool GetVersionEx2( ref OSVersionInfo2 osvi );  
    }
    // 函数调用:
    public class App
    {
       public static void Main()
       {
          Console.WriteLine( "\nPassing OSVersionInfo as class" );      OSVersionInfo osvi = new OSVersionInfo();
          osvi.OSVersionInfoSize = Marshal.SizeOf( osvi );      LibWrap.GetVersionEx( osvi );
          
          Console.WriteLine( "Class size:    {0}", osvi.OSVersionInfoSize );
          …
          Console.WriteLine( "\nPassing OSVersionInfo as struct" );      OSVersionInfo2 osvi2 = new OSVersionInfo2();
          osvi2.OSVersionInfoSize = Marshal.SizeOf( osvi2 );      LibWrap.GetVersionEx2( ref osvi2 );
          Console.WriteLine( "Struct size:   {0}", osvi2.OSVersionInfoSize );
          …     
       }
    }
    我参照它的用法这样写:// 结构定义:
        [StructLayout(LayoutKind.Sequential)]
        public struct JBNV_ServerInfo
        {
            public uint dwSize;         // 结构大小
            public uint dwServerFlag;   // 服务器类型
            public uint dwServerIp;     // 服务器IP(整数表示形式)
            [MarshalAs(UnmanagedType.ByValTStr, SizeConst = 16)]
            public string szServerIp;   // 服务器IP(字符串表示形式) 
            public UInt16 wServerPort;    // 服务器端口
            public UInt16 wChannelNum;    // 通道数量
            public uint dwVersionNum;   // 版本
            [MarshalAs(UnmanagedType.ByValTStr, SizeConst = 32)]
            public string szServerName;
            public uint dwServerCPUType;    // 当前CPU类型
            [MarshalAs(UnmanagedType.ByValArray, ArraySubType = UnmanagedType.U1, SizeConst = 48)]
            public byte[] bServerSerial;
            [MarshalAs(UnmanagedType.ByValArray, ArraySubType = UnmanagedType.U1, SizeConst = 6)]
            public byte[] byMACAddr;
            uint dwAlarmInCount;        // 告警输入个数
            uint dwAlarmOutCount;       // 告警输出个数
            uint dwSysFlags;        // 系统支持的功能
            uint dwUserRight;       // 当前用户权限
            uint dwNetPriviewRight; // 网络观看权限
            [MarshalAs(UnmanagedType.ByValTStr, SizeConst = 64)]
            public string csServerDes;
        }// 函数声明:
            [DllImport("JBNVSDK.dll", CharSet = CharSet.Ansi)]
            public extern static JBNV_ErrorCode JBNV_GetServerInfo(IntPtr hServer, ref JBNV_ServerInfo serverInfo);
    // 函数调用:
                JBNV_ServerInfo serverInfo = new JBNV_ServerInfo();
              re = JBNV_DLLFuction.JBNV_GetServerInfo(hServer, ref serverInfo);
    出现一个异常:尝试读取或写入受保护的内存。这通常指示其他内存已损坏。这很奇怪,如果说是byte[]的问题,但是一楼那种写法并没有出现异常,那么只能是string的错误了。求解。
      

  5.   

    public extern static Int32 JBNV_GetServerInfo(IntPtr hServer, /*ref*/ IntPtr serverInfo);调用:IntPtr serverInfo = Marshal.AllocHGlobal(Marshal.SizeOf(typeof(JBNV_ServerInfo)));
                re = JBNV_DLLFuction.JBNV_GetServerInfo(hServer, serverInfo);
                JBNV_ServerInfo info = (JBNV_ServerInfo)Marshal.PtrToStructure(serverInfo, typeof(JBNV_ServerInfo));
                Marshal.FreeHGlobal(serverInfo);
      

  6.   

    问题解决了,不是类型转换的问题,MSDN上写的那种方式是完全正确的。
    我的问题出在了结构里有一个参数表征数据结构大小的字段,这个字段要赋值后才能传入,否则的话就会出现参数不正确的错误。这个也是看MSDN上的例子突然想起来的,在视频服务器的SDK说明上根本没有提要赋值才能传入,我没有这方面的编程经验,属于自己在粗心了...
    谢谢大家,结贴!
      

  7.   


    to :jointan
    您的这个方法我试了,确实可以正确传入,但是可能是因为表示结构大小的字段没有赋值,所以传出来的结果有问题。我还不知道怎么给函数Marshal.AllocHGlobal分配的内存写入值,所以没有测试到底正不正确。我会留心以后会了再来测试一下的。再次谢谢大家。