c# 转换 c++ 结构体中的char**

我是菜鸟999 2016-07-27 09:34:01

typedef struct struct_DATA_OPEN_SETTINGS
{
char szUserID[DEFAULT_SIZE]; //用户名
char szPassword[DEFAULT_SIZE]; //密码
char** pp; //数组
int nCount; //个数

pfnOnMsg pfnMsg;
pfnOnData pfnData;
}DATA_OPEN_SETTINGS;


上面结构体中的char** pp怎么在C#里面用?


[StructLayout(LayoutKind.Sequential, CharSet = CharSet.Ansi)]
public struct DATA_OPEN_SETTINGS
{
[MarshalAs(UnmanagedType.ByValTStr, SizeConst = 25)]
public string pszUserID;

[MarshalAs(UnmanagedType.ByValTStr, SizeConst = 25)]
public string pszPassword;

//[MarshalAs(UnmanagedType.ByValArray, SizeConst = 2)]
public string[] pp;

public int nCount;

public CallbackDelegateMsg callbackMsg;

public CallbackDelegateData callbackData;
}


这样写不行。
请教大神,应该怎么写?
...全文
385 7 打赏 收藏 转发到动态 举报
写回复
用AI写文章
7 条回复
切换为时间正序
请发表友善的回复…
发表回复
  • 打赏
  • 举报
回复
严格来说,C#中的string只能对应C++中的const char*,因为具有不可变性。 ToLower() SubString() 其实都只是生成新字符串再返回,如果使用不当,就会影响性能 回到你的问题,如果你只是获取对方的值,可以用string 如果对方需要修改pp(缓冲),用string[] 肯定是不行的,最起码得用StringBuilder(但托管堆由于会回收导致地址变动,仍然会有问题),所以最保险的像LS那样直接在非托管内在中申请缓冲区 至于需不需要初始化(初始化多大空间),这是开发协议上的事了
我是菜鸟999 2016-07-27
  • 打赏
  • 举报
回复
引用 5 楼 Forty2 的回复:
再次更正:) public void 销毁数组pp() { for (int i = 0; i < nCount; i++) { IntPtr 缓冲区指针 = Marshal.ReadIntPtr(pp + (IntPtr.Size) * i); Marshal.FreeHGlobal(缓冲区指针); // FreeHGlobal对应StringToHGlobalxxx } Marshal.FreeHGlobal(pp); // FreeHGlobal对应AllocHGlobal }
对了~太牛了!感谢!!!
Forty2 2016-07-27
  • 打赏
  • 举报
回复
再次更正:) public void 销毁数组pp() { for (int i = 0; i < nCount; i++) { IntPtr 缓冲区指针 = Marshal.ReadIntPtr(pp + (IntPtr.Size) * i); Marshal.FreeHGlobal(缓冲区指针); // FreeHGlobal对应StringToHGlobalxxx } Marshal.FreeHGlobal(pp); // FreeHGlobal对应AllocHGlobal }
Forty2 2016-07-27
  • 打赏
  • 举报
回复
public void CreatePIns(string[] strIns)
{
    nCount = strIns.Length;
    pp = Marshal.AllocHGlobal(IntPtr.Size * nCount);
    for (int i = 0; i < nCount; i++)
    {
        IntPtr 缓冲区指针 = Marshal.StringToHGlobalAnsi(strIns[i]);   // 或Marshal.StringToHGlobalUni,取决于你C++库的字符编码。
        Marshal.WriteIntPtr(pp + (IntPtr.Size) * i, 缓冲区指针);
    }
}
public void 销毁数组pp()
{
    for (int i = 0; i < nCount; i++)
    {
        IntPtr 缓冲区指针 = pp + (IntPtr.Size) * i;
        Marshal.FreeHGlobal(缓冲区指针);  // FreeHGlobal对应StringToHGlobalxxx
    }
    Marshal.FreeHGlobal(pp);  // FreeHGlobal对应AllocHGlobal
}
我是菜鸟999 2016-07-27
  • 打赏
  • 举报
回复
引用 2 楼 Forty2 的回复:
更正: Marshal.WriteIntPtr(pp + (IntPtr.Size) * i, 缓冲区指针);[/quo [quote=引用 2 楼 Forty2 的回复:] 更正: Marshal.WriteIntPtr(pp + (IntPtr.Size) * i, 缓冲区指针);
请问,IntPtr 缓冲区指针 = Marshal.AllocHGlobal(最大缓冲长度);分配内存之后,如何把我外部的数据拷到这块内存上?

public void CreatePIns(string[] strIns)
            {
                nCount = strIns.GetLength(0);
                pIns = Marshal.AllocHGlobal(IntPtr.Size * nCount);
                for (int i = 0; i < nCount;i++ )
                {
                    IntPtr pTmp = Marshal.AllocHGlobal(strIns[i].Length+1);
                    Marshal.StructureToPtr(strIns[i], pTmp, true);
                    //pTmp = GCHandle.ToIntPtr(GCHandle.Alloc(strIns[i]));
                    Marshal.WriteIntPtr(pIns + (IntPtr.Size) * i, pTmp);
                }
            }
这样报错 “System.ArgumentException”类型的未经处理的异常出现在 ECenter.exe 中。 其他信息: 指定结构必须能直接复制到本机结构中,或是具有布局信息。
Forty2 2016-07-27
  • 打赏
  • 举报
回复
更正: Marshal.WriteIntPtr(pp + (IntPtr.Size) * i, 缓冲区指针);
Forty2 2016-07-27
  • 打赏
  • 举报
回复
引用 楼主 u013533826 的回复:
... 这样写不行。 请教大神,应该怎么写?
不可以。
[StructLayout(LayoutKind.Sequential, CharSet = CharSet.Ansi)]
public struct DATA_OPEN_SETTINGS
{
    //...
    public IntPtr pp;    // 用IntPtr来传入char**
    public int nCount;
    //...

    public void 准备数组pp(int 个数, int 最大缓冲长度)
    {
        nCount = 个数;
        pp = Marshal.AllocHGlobal(IntPtr.Size * nCount);

        for(int i = 0; i<nCount; i++)
        {
            IntPtr 缓冲区指针 = Marshal.AllocHGlobal(最大缓冲长度);
            Marshal.WriteIntPtr(pp + (IntPtr.Size), 缓冲区指针);
        }
    }
    public void 销毁数组pp()
    {
        // 要记得销毁...
    }
}

111,129

社区成员

发帖
与我相关
我的任务
社区描述
.NET技术 C#
社区管理员
  • C#
  • Creator Browser
  • by_封爱
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告

让您成为最强悍的C#开发者

试试用AI创作助手写篇文章吧