C#调用C++ DLL(结构体中二维数组转换)

时间:2022-08-30 19:43:30
  想在C# WinForm开发中调用一个采用C++封装好的dll, 但其结构体中的二维数组不知道应当如何转换, 网上搜索了一把P/Invoke资料相对来说比较少, 没有找到切实有用的文章, 现在调用虽不会报错了, 但没有产生预期效果.


#define MAX_STRM_LAYER 3  // 最多几级流媒体
//服务器信息
typedef struct tagServerInfo
{
     long uID;                     
     char csStrMIP[MAX_STRM_LAYER][16];  // 这个不知道如何转换       
     unsigned short nStrMPort[MAX_STRM_LAYER];  

     char csDdtIP[16];             
     unsigned short nDdtPort;      
     unsigned short bIsWebUser;    

     unsigned short protocolType;  
     const char *pcUserName;       
     const char *pcPassword;       

     char csStoreFileSvrIP[16];         
     unsigned short nStoreFileSvrPort;  

     char csDevFileSvrIP[16];           
     unsigned short nDevFileSvrPort;    

}TServerInfo, *LPServerInfo;

LONG __stdcall StrM_Login(LPServerInfo mts, int iLayer = 1);



/// <summary>
/// 最多几级流媒体
/// </summary>
public const int MAX_STRM_LAYER = 3;

        /// <summary>
        /// 服务器信息
        /// </summary>
        [StructLayoutAttribute(LayoutKind.Sequential, CharSet = CharSet.Ansi)]
        public struct TServerInfo
        {
            public int uID;
            [MarshalAsAttribute(UnmanagedType.ByValArray, SizeConst = 3, ArraySubType = UnmanagedType.LPStr)]
            public string[] csStrMIP;

            public ushort[] nStrMPort;

            [MarshalAsAttribute(UnmanagedType.ByValTStr, SizeConst = 16)]
            public string csDdtIP;

            public ushort nDdtPort;

            public ushort bIsWebUser;

            public ushort protocolType;

            public string pcUserName;

            public string pcPassword;

            [MarshalAsAttribute(UnmanagedType.ByValTStr, SizeConst = 16)]
            public string csStoreFileSvrIP;

            public ushort nStoreFileSvrPort;

            [MarshalAsAttribute(UnmanagedType.ByValTStr, SizeConst = 16)]
            public string csDevFileSvrIP;
 
            public ushort nDevFileSvrPort;
        }

        [DllImport("StreamMedia.dll")]
        public static extern int StrM_Login(ref TServerInfo mts, int iLayer);

10 个解决方案

#1


关 注

#2


C++的多维数组,转成C#的一维数组处理


        [StructLayoutAttribute(LayoutKind.Sequential, CharSet = CharSet.Ansi)]
        public struct TServerInfo
        {   
            [MarshalAsAttribute(UnmanagedType.ByValArray, SizeConst = 3*16]
            public char[] csStrMIP;
        }


刚自己写的试验代码


typedef struct tagSvrInfo
{
  char csStrMIP[3][16];
}TSvrInfo,*LPSvrInfo

//assign char value 'a','b','c'
PIDLL_API void Login(LPSvrInfo info)
{
info->csStrMIP[0][0] = 'a';
info->csStrMIP[1][0] = 'b';
info->csStrMIP[2][0] = 'c';
}

extern "C"
{
   PIDLL_API void Login(LPSvrInfo info);
};




        [DllImport("pidll.dll")]
        static extern int Login(ref SvrInfo info);

        [StructLayoutAttribute(LayoutKind.Sequential, CharSet = CharSet.Ansi)]
        public struct SvrInfo
        {
            [MarshalAs(UnmanagedType.ByValArray, SizeConst = 3 * 16)]
            public char[] csStrMIP;
        }

        static void Main(string[] args)
        {
            SvrInfo si = new SvrInfo();
            si.csStrMIP = new char[48];

            Login(ref si);

            Console.WriteLine(si.csStrMIP[0]);
            Console.WriteLine(si.csStrMIP[16]);
            Console.WriteLine(si.csStrMIP[32]);
        }

        /*---------------输出为----------
        a
        b
        c
        ------------------------------*/

#3


引用 2 楼 bloodish 的回复:
C++的多维数组,转成C#的一维数组处理

C# code

        [StructLayoutAttribute(LayoutKind.Sequential, CharSet = CharSet.Ansi)]
        public struct TServerInfo
        {   
            [MarshalAsAttribute(Unmanag……


学习 

#4


up......

#5


转换成一维数组处理,注意长度就行。

#6


好高端啊,先顶后学

#7


                                
   DING  YI  GE

#8


根据2楼方法解决, 还有原先代码忘记给数组指定元素个数了

[StructLayoutAttribute(LayoutKind.Sequential, CharSet = CharSet.Ansi)]
        public struct TServerInfo
        {
            public int uID;

            [MarshalAsAttribute(UnmanagedType.ByValArray, SizeConst = 3 * 16)]
            public char[] csStrMIP;

            [MarshalAsAttribute(UnmanagedType.ByValArray, SizeConst = 3)] // 这里原先忘记指定了
            public ushort[] nStrMPort;

            [MarshalAsAttribute(UnmanagedType.ByValTStr, SizeConst = 16)]
            public string csDdtIP;

            public ushort nDdtPort;

            public ushort bIsWebUser;

            public ushort protocolType;

            public string pcUserName;

            public string pcPassword;

            [MarshalAsAttribute(UnmanagedType.ByValTStr, SizeConst = 16)]
            public string csStoreFileSvrIP;

            public ushort nStoreFileSvrPort;

            [MarshalAsAttribute(UnmanagedType.ByValTStr, SizeConst = 16)]
            public string csDevFileSvrIP;
 
            public ushort nDevFileSvrPort;
        }

#9


我是来学习的

#10


学习了,正在为这个事情头痛,CLR搞死人啊

#1


关 注

#2


C++的多维数组,转成C#的一维数组处理


        [StructLayoutAttribute(LayoutKind.Sequential, CharSet = CharSet.Ansi)]
        public struct TServerInfo
        {   
            [MarshalAsAttribute(UnmanagedType.ByValArray, SizeConst = 3*16]
            public char[] csStrMIP;
        }


刚自己写的试验代码


typedef struct tagSvrInfo
{
  char csStrMIP[3][16];
}TSvrInfo,*LPSvrInfo

//assign char value 'a','b','c'
PIDLL_API void Login(LPSvrInfo info)
{
info->csStrMIP[0][0] = 'a';
info->csStrMIP[1][0] = 'b';
info->csStrMIP[2][0] = 'c';
}

extern "C"
{
   PIDLL_API void Login(LPSvrInfo info);
};




        [DllImport("pidll.dll")]
        static extern int Login(ref SvrInfo info);

        [StructLayoutAttribute(LayoutKind.Sequential, CharSet = CharSet.Ansi)]
        public struct SvrInfo
        {
            [MarshalAs(UnmanagedType.ByValArray, SizeConst = 3 * 16)]
            public char[] csStrMIP;
        }

        static void Main(string[] args)
        {
            SvrInfo si = new SvrInfo();
            si.csStrMIP = new char[48];

            Login(ref si);

            Console.WriteLine(si.csStrMIP[0]);
            Console.WriteLine(si.csStrMIP[16]);
            Console.WriteLine(si.csStrMIP[32]);
        }

        /*---------------输出为----------
        a
        b
        c
        ------------------------------*/

#3


引用 2 楼 bloodish 的回复:
C++的多维数组,转成C#的一维数组处理

C# code

        [StructLayoutAttribute(LayoutKind.Sequential, CharSet = CharSet.Ansi)]
        public struct TServerInfo
        {   
            [MarshalAsAttribute(Unmanag……


学习 

#4


up......

#5


转换成一维数组处理,注意长度就行。

#6


好高端啊,先顶后学

#7


                                
   DING  YI  GE

#8


根据2楼方法解决, 还有原先代码忘记给数组指定元素个数了

[StructLayoutAttribute(LayoutKind.Sequential, CharSet = CharSet.Ansi)]
        public struct TServerInfo
        {
            public int uID;

            [MarshalAsAttribute(UnmanagedType.ByValArray, SizeConst = 3 * 16)]
            public char[] csStrMIP;

            [MarshalAsAttribute(UnmanagedType.ByValArray, SizeConst = 3)] // 这里原先忘记指定了
            public ushort[] nStrMPort;

            [MarshalAsAttribute(UnmanagedType.ByValTStr, SizeConst = 16)]
            public string csDdtIP;

            public ushort nDdtPort;

            public ushort bIsWebUser;

            public ushort protocolType;

            public string pcUserName;

            public string pcPassword;

            [MarshalAsAttribute(UnmanagedType.ByValTStr, SizeConst = 16)]
            public string csStoreFileSvrIP;

            public ushort nStoreFileSvrPort;

            [MarshalAsAttribute(UnmanagedType.ByValTStr, SizeConst = 16)]
            public string csDevFileSvrIP;
 
            public ushort nDevFileSvrPort;
        }

#9


我是来学习的

#10


学习了,正在为这个事情头痛,CLR搞死人啊