返回包含带有PInvoke的char []的struct的结构数组

时间:2012-01-06 14:20:57

标签: c# pinvoke

我有一个从PInvoke返回的结构数组,如果结构只包含int或float,它会返回数组,但是当我尝试返回一个char数组时,它开始变得混乱,我试过返回一个IntPtr,但这还没有成功。任何想法我怎么能让这个工作?

C代码

struct  return_part {
    int partid;
    int numcomp;
    int parttype;
    char partname[100];
};

extern int return_parts(return_part ** array, int * arraySizeInElements) {
    int partcount = 0;
    struct list_part *currentnode; 
    currentnode = head;
    struct section_list *section;
    struct return_part *temppart;

    while (currentnode != NULL) {
        partcount++;
        currentnode = currentnode->next;
    }

    currentnode = head;
    *arraySizeInElements = partcount;

    int bytesToAlloc = sizeof(return_part) * (*arraySizeInElements);
    return_part * a = static_cast<return_part *>(CoTaskMemAlloc(bytesToAlloc));
    *array = a;

    int q = 0;
    while (currentnode != NULL) {
        struct return_part tmp;
        tmp.partid = currentnode->partid;
        tmp.numcomp = currentnode->numcomp;
        strcpy(tmp.partname, currentnode->partname);
        tmp.parttype = currentnode->parttype;

        a[q] = tmp;
        q++;
        currentnode = currentnode->next;
    }

    return 0;
}

C#代码

[StructLayout(LayoutKind.Sequential)]
public struct return_part {
    public int partid;
    public int numcomp;
    public int parttype;
    public char partname;
};

internal static class UnsafeNativeMethods
{
    [DllImport(_dllLocation, CallingConvention = CallingConvention.Cdecl)]
    public static extern int return_parts([MarshalAs(UnmanagedType.LPArray,
    SizeParamIndex = 1)] out return_part[] array, out int arraySizeInElements);
}

public static ReturnPoint[] getpoints(int partid) {
    return_parts[] parts;
    int size;
    int result = UnsafeNativeMethods.return_parts(out parts, out size)
}

2 个答案:

答案 0 :(得分:4)

非托管代码的字符数组只是一个字符串,因此这里有两个选项。您使用哪一个取决于您在C#-land中返回时实际需要如何使用字符数据:

  1. 将其作为阵列进行分类。请参阅this article了解嵌入到结构中的数组是如何编组的(编辑:这需要是ByValArray,而不是我最初指出的LPArray;感谢@Hans):

    [StructLayout(LayoutKind.Sequential)]
    public struct return_part {
        public int partid;
        public int numcomp;
        public int parttype;
        [MarshalAs(UnmanagedType.ByValArray, SizeConst=100)]
        public char[] partname;
    };
    
  2. 将其标记为字符串。有关如何编组结构中包含的字符串,请参阅this article

    [StructLayout(LayoutKind.Sequential)]
    public struct return_part {
      public int partid;
      public int numcomp;
      public int parttype;
      [MarshalAs(UnmanagedType.ByValTStr, SizeConst=100)]
      public string partname;
    };
    

答案 1 :(得分:1)

在C#端,您的结构只有一个字符作为partname。尝试使用:

char[] partname; //-- A character array

byte[] partname; //-- A byte array

string partname; //-- A string

如果有效,我倾向于选择字符串。这个字节可能有效,因为C#中的字符在C语言中更符合逻辑排列。字符数组也可以工作,因为C#中的字符逻辑上代表一个实际的单个字符(预期用途),C实际上并没有(缺少unsigned)整数类型)。