C# 如何将字符串数组复制到非托管字符双指针中?

C# 如何将字符串数组复制到非托管字符双指针中?,c#,char,marshalling,unmanaged-memory,C#,Char,Marshalling,Unmanaged Memory,我在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').ToCharArr

我在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);
    }
}
这个
mallocary2d
方法被调用到
MallocImage
中,它在我的C#code中公开

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

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

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

}
现在,我的C#exposed
MallocImage
方法:

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;
}
[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"];

System.Char
是一个unicode 16位字符[]。您可能使用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);
    }
}
公共静态无效StringArrayToPtr(IntPtr ptr,string[]数组)
{
for(int i=0;i
A
System.Char
是一个unicode 16位字符[]。您可能使用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);
    }
}
公共静态无效StringArrayToPtr(IntPtr ptr,string[]数组)
{
for(int i=0;i
I调试C代码中的
char**names
,并且
names[0]
返回以下内容:“
names
数组分配是否正确?”?您在C代码中使用的指针是否与
名称的地址匹配?如果答案是肯定的,那么您必须显示您的C代码,并描述两者之间的交互(分配发生时,如何检索指针,何时尝试设置数据等)。C中的
&name
和C中的
&ptr
似乎不匹配。这就是控制指针地址的方法吗?我还更新了我的答案,效果很好!!非常感谢你。我知道我必须找回指针,但不知道怎么做。再次使用Thx。我调试C代码中的
char**names
,并且
names[0]
返回以下内容:“
names
数组分配是否正确?”?您在C代码中使用的指针是否与
名称的地址匹配?如果答案是肯定的,那么您必须显示您的C代码,并描述两者之间的交互(分配发生时,如何检索指针,何时尝试设置数据等)。C中的
&name
和C中的
&ptr
似乎不匹配。这就是控制指针地址的方法吗?我还更新了我的答案,效果很好!!非常感谢你。我知道我必须找回指针,但不知道怎么做。再次感谢您的编辑。仍然缺少一个重要的部分:如何从C代码中调用
mallocary2D
?同样假设您是,您是否在
StringArrayToPtr
方法中使用
p2
指针?我在
StringArrayToPtr
方法中使用的指针是我的C类的
IntPtr名称
。我猜它对应于
p2
指针,通过编组过程,您可以验证
Image
类的
IntPtr名称是否与
Image
结构中的指针匹配吗?如果没有,请发布您的
图像
结构。两个指针匹配。请查看我编辑的答案谢谢编辑。仍然缺少一个重要的部分:如何从C代码中调用
mallocary2D
?同样假设您是,您是否在
StringArrayToPtr
方法中使用
p2
指针?我在
StringArrayToPtr
方法中使用的指针是我的C类的
IntPtr名称
。我猜它对应于
p2
指针,通过编组过程,您可以验证
Image
类的
IntPtr名称是否与
Image
结构中的指针匹配吗?如果没有,请发布您的
图像
结构。两个指针匹配。请查看我编辑的答案