Маршалинг двумерного массива char фиксированной длины в C ++ в качестве члена структуры - PullRequest
4 голосов
/ 15 февраля 2010

Я пытаюсь вызвать неуправляемую функцию C ++, которая имеет структуру в качестве входного параметра. Структура определяется в заголовочном файле следующим образом:

struct MyStruct
{
int     siOrder;
char     aaszNames[6][25];
int     siId[6];
int     siTones[6];        
};

Я пытался объявить управляемую структуру следующим образом:

[StructLayoutAttribute(LayoutKind.Sequential, CharSet=CharSet.Ansi)]
public struct MyStruct {

public int siOrder;

[MarshalAsAttribute(UnmanagedType.ByValTStr, SizeConst=150)]
public string aaszNames;

[MarshalAsAttribute(UnmanagedType.ByValArray, SizeConst=6, ArraySubType=UnmanagedType.I4)]
public int[] siId;

[MarshalAsAttribute(UnmanagedType.ByValArray, SizeConst=6, ArraySubType=UnmanagedType.I4)]
public int[] siTones;
}

Но безуспешно. Я предполагаю, что маршалинг завершился неудачно, поскольку aaszNames на самом деле представляет собой массив из шести длинных строк с нулем в конце, равных 25 Я пытался объявить aaszNames как

 [MarshalAsAttribute(UnmanagedType.ByValArray, SizeConst=150)]
 public char[] aaszNames;

заполнение массива нулями, где это необходимо. Но опять же ничего.

Есть что-то, чего мне не хватает? Что я не прав? Каков наилучший способ упорядочить этот массив двумерных символов?

Любые подсказки, пожалуйста.

Ответы [ 4 ]

7 голосов
/ 22 августа 2011

Попробуйте использовать несколько структур C #:

[StructLayoutAttribute(LayoutKind.Sequential, CharSet=CharSet.Ansi)]
public struct MyStruct_Name
{
    [MarshalAsAttribute(UnmanagedType.ByValTStr, SizeConst = 25)]
    public string name;
}

[StructLayoutAttribute(LayoutKind.Sequential, CharSet = CharSet.Ansi)]
public struct MyStruct
{
    public int siOrder;

    [MarshalAsAttribute(UnmanagedType.ByValArray, SizeConst = 6)]
    public MyStruct_Name aaszNames;

    [MarshalAsAttribute(UnmanagedType.ByValArray, SizeConst = 6, ArraySubType = UnmanagedType.I4)]
    public int[] siId;

    [MarshalAsAttribute(UnmanagedType.ByValArray, SizeConst = 6, ArraySubType = UnmanagedType.I4)]
    public int[] siTones;
}

Так я передавал массивы строк в стиле C.

Не забудьте создать содержимое aaszNames! Маршаллер ненавидит нулевые ссылки.

MyStruct foo = new MyStruct();
for (int i = 0; i < 6; i++)
{
    foo.aaszNames[i] = new MyStruct_Name();
    foo.aaszNames[i].name = "";
}

Удачи!

0 голосов
/ 16 февраля 2010

Я бы написал небольшую c-программу для проверки размера байта C-структуры.
Тогда я бы пошел с другим предложением, чтобы извлечь поле данных по полю.
С точки зрения C / 0 обрабатывается как обычный символ, включенный в 6 байтов, тогда как C # будет использовать длину 5 и иметь скрытый / 0.

0 голосов
/ 15 июня 2011
char aaszNames[6][25];

символ типа C ++ - 8 битов ~

но символ типа C # - это Unicode, (16 бит)!

so char типа C ++ <-> байт типа C #

0 голосов
/ 15 февраля 2010
[MarshalAsAttribute(UnmanagedType.ByValArray, SizeConst=150)]
 public char[] aaszNames;

Этот тип сортировки выглядит хорошо. Возможно, проблема в вызове функции или неправильное распределение памяти /

...