【问题标题】:Returning an array of structs with struct containing char[] with PInvoke使用 PInvoke 返回一个结构数组,其结构包含 char[]
【发布时间】:2012-01-07 05:24:30
【问题描述】:

我有一个从 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)
}

【问题讨论】:

    标签: c# pinvoke


    【解决方案1】:

    对于非托管代码而言,字符数组只是一个字符串,因此您有两种选择。您使用哪一种取决于您在返回 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;
      };
      

    【讨论】:

    • LPArray 不正确,将其转换为 char*,而不是 char[]。第二个sn-p很好。
    • 我的错,你是对的;数组/指针等价仅在函数参数中是正确的,而不是嵌入到结构中。编辑来解决这个问题。
    【解决方案2】:

    在 C# 方面,您的结构有一个字符作为部件名。尝试使用:

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

    如果可行的话,我会倾向于选择字符串。字节可能会起作用,因为 C# 中的 byte 与 C 中的 char 在逻辑上排列得更紧密。字符数组也可能起作用,因为 C# 中的字符在逻辑上代表一个实际的单个字符(预期用途),而 C 没有真正具有的东西(缺少无符号整数类型)。

    【讨论】:

      猜你喜欢
      • 2021-06-17
      • 1970-01-01
      • 2012-02-05
      • 2019-05-06
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多