Marshaling структуры, содержащей массив структур, содержащих структуры
От: Albeoris  
Дата: 15.11.13 13:42
Оценка:
Доброго времени суток!

WinAPI'ый метод принимает на вход указатель на структуру Top.

[StructLayout(LayoutKind.Sequential, CharSet = CharSet.Auto)]
struct Top
{
  int Count;       // DWORD
  Middle[] Childs; // Указатель на массив
}

[StructLayout(LayoutKind.Sequential, CharSet = CharSet.Auto)]
struct Middle
{
  [MarshalAs(UnmanagedType.LPStr)]
  string ID;   // LPSTR
  bool Flag;   // BOOL
  Bottom Data; // Не указатель
}

[StructLayout(LayoutKind.Sequential, CharSet = CharSet.Auto)]
struct Bottom 
{
  int Size;       // Размер данных
  IntPtr DataPtr; // Указатель на данные
}



Вызов:
[DllImport("MyLib.dll", CharSet = CharSet.Auto, SetLastError = true)]
public static extern bool MyFunc([In] ref Top topStruct);

Завершается с ошибкой:
Параметр задан неверно. (Исключение из HRESUL: 0x80070057 (E_INVALIDARG))

В чём я не прав? Неверно передался дочерний массив? ref для структуры не подходит, как замена указателя?
"Хаос всегда побеждает порядок, поскольку лучше организован." (с) Терри Пратчетт
Re: Marshaling структуры, содержащей массив структур, содержащих структуры
От: SanyaVB  
Дата: 15.11.13 17:06
Оценка:
Здравствуйте, Albeoris, Вы писали:

A>Доброго времени суток!


A>WinAPI'ый метод принимает на вход указатель на структуру Top.


A>
A>[StructLayout(LayoutKind.Sequential, CharSet = CharSet.Auto)]
A>struct Top
A>{
A>  int Count;       // DWORD
A>  Middle[] Childs; // Указатель на массив
A>}
A>



У тебя для Middle[] Childs не определен атрибут MarshalAs
Re[2]: Marshaling структуры, содержащей массив структур, содержащих структуры
От: Albeoris  
Дата: 25.11.13 11:21
Оценка:
Здравствуйте, SanyaVB, Вы писали:
SVB>У тебя для Middle[] Childs не определен атрибут MarshalAs
При его отсутствии, используется дефолтный. По дефолту массивы маршалятся, как LPArray.

Проблему решил.
Причин ошибки две:
1) В .NET элементы массива могут храниться не единым массивом, даже если это структуры, а не классы (непроверенные данные). В итоге всё-таки выделил новый кусок памяти и скопировал в него данные из массива.
2) Ошибка в подсчётах размеров и неверный тип данных (значение, вместо указателя) в одной из структур.

Нашёл и ликвидировал, создав в С++ DLL, с заглушками для функций, принимающих подобные параметры, после чего смотрел — как смаршаленые значения выглядят в Unmanaged памяти.

Спасибо за внимание.
"Хаос всегда побеждает порядок, поскольку лучше организован." (с) Терри Пратчетт
 
Подождите ...
Wait...
Пока на собственное сообщение не было ответов, его можно удалить.