Возвращение массива структур со структурой, содержащей char [], с помощью PInvoke - PullRequest
3 голосов
/ 06 января 2012

У меня есть массив структур, возвращаемых из 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 ]

4 голосов
/ 06 января 2012

Массив символов для неуправляемого кода - это просто строка, поэтому у вас есть два варианта здесь. Какой из них вы используете, зависит от того, как вам на самом деле нужно использовать символьные данные, когда они вернулись в C # -land:

  1. Маршал это как массив. См. в этой статье о том, как маршализовать массивы, встроенные в структуры (EDIT: это должен быть 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. Маршал это как строка. См. в этой статье о том, как упорядочить строки, содержащиеся в структурах.

    [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 голос
/ 06 января 2012

На стороне C # ваша структура имеет один символ в качестве partname.Попробуйте использовать:

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

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

string partname; //-- A string

Я бы предпочел строку, если это работает.Байт может работать, потому что байт в C # выстраивается более логично с char в C. Массив символов также может работать, потому что символ в C # логически представляет фактический одиночный символ (предполагаемое использование), чего у C на самом деле нет (если не считать беззнакового)целочисленные типы).

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...