【问题标题】:How can I copy a array of strings into an unmanaged char double pointer?如何将字符串数组复制到非托管 char 双指针中?
【发布时间】:2013-06-13 15:55:22
【问题描述】:

我在 C 结构中有一个 char**,它在 C 代码中分配为 Nx128 矩阵。在 C# 中,我有一个字符串数组,我想将此数组复制到 char 双指针,而不重新分配任何内容。我试过这个:

public void StringArrayToPtr(IntPtr ptr, string[] array) 
{

    for (int i = 0; i < array.Length; i++)
    {
        char[] chars = (array[i] + '\0').ToCharArray();

        Marshal.Copy(chars, 0, IntPtr.Add(ptr, 128*i), chars.Length);
    }
}

但这不起作用。 有人知道如何进行这样的复制吗?

更新:

这是我的char** names 在 C 代码中分配 3 个项目的方式:names = (char **) MallocArray2D (3, 128, sizeof ( char ));

这里是MallocArray2D方法的详细信息:

void ** MallocArray2D (
     int  n1,
     int  n2,
     int  size_elem )
{
    void ** p2;
    void * p1;
    size_t i;

    p1 = (void *) malloc (size_elem * n1 * n2); 

    p2 = (void **) malloc (n1 * sizeof ( void * ));


    for ( i = 0 ; i < n1 ; i++ )
    {
        p2[i] = (char *) p1 + size_elem * n2 * i;
    }

    return p2;
}

这个MallocArray2D 方法被调用到一个MallocImage 中,它在我的C# 代码中公开。

这是 C 代码中有趣的 MallocImage 方法部分:

int MallocImage (
     IMAGE *  image,
     int           nxyz,
     int           nvar )
{
    //... Allocating others objects

    image->names = (char **) MPDSMallocArray2D ( nvar, 128, sizeof ( char ));

}

现在我的 C# 暴露了MallocImage 方法:

[DllImport(DLL_PATH, CallingConvention = CallingConvention.Cdecl)]
public static extern int MallocImage([In, Out]Image image, int nXYZ, int nVar);

// My Image class
[StructLayout(LayoutKind.Sequential)]
class Image {

    private IntPtr names;

    public string[] Names {

        set {ArrayOfStringToPtr(names, value);}

    }

    // Constructor
    public Image(int nVar, int nXYZ) {

        MallocImage(this, nXYZ, nVar);

    }

}


// Somewhere else in my code
image.Names = new string[] {"porosity", "duplicity", "facies"];

【问题讨论】:

  • 感谢您的编辑。仍然缺少一个重要部分:如何从 C# 代码中调用 MallocArray2D?还假设你是,你是否在StringArrayToPtr 方法中使用p2 指针?
  • 我在StringArrayToPtr 方法中使用的指针是我的C# 类的IntPtr names。我猜它对应p2指针,通过Marshalling过程
  • 您能否验证Image 类的IntPtr names 是否与IMAGE 结构中的指针匹配?如果没有,请发布您的 IMAGE 结构。
  • 两个指针匹配。
  • 请看我编辑的答案

标签: c# char marshalling unmanaged-memory


【解决方案1】:

System.Char 是一个 unicode 16 位字符 [MSDN]。您可能使用 ASCII 字符串。

这里的指针算法似乎是错误的,因为您正在使用 一个指向三个指针数组的指针,您可能需要使用:Marshal.ReadIntPtr(ptr, i * IntPtr.Size) 来获取字符串的地址,因此结果是代码将是:

public static void StringArrayToPtr(IntPtr ptr, string[] array)
{
    for (int i = 0; i < array.Length; i++)
    {
        byte[] chars = System.Text.Encoding.ASCII.GetBytes(array[i] + '\0');
        Marshal.Copy(chars, 0, Marshal.ReadIntPtr(ptr, i * IntPtr.Size), chars.Length);
    }
}

【讨论】:

  • 我在 C 代码中调试 char** namesnames[0] 返回:“
  • 您的names 数组分配正确吗?您在 C# 代码中使用的指针是否与names 的地址匹配?如果答案是肯定的,那么您将必须展示您的 C 代码并描述两者之间的交互(分配发生时,您如何检索指针,您何时尝试设置数据等...)跨度>
  • C 中的 &amp;names 和 C# 中的 &amp;ptr 似乎不匹配。这是控制指针地址的方法吗?我也更新了我的答案
  • 效果很好!!非常感谢。我知道我必须检索指针,但不知道该怎么做。再次感谢。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2020-11-04
  • 2020-12-13
  • 1970-01-01
相关资源
最近更新 更多