У меня есть следующие (сокращенная) определение функции в моем C++ код:типа Marshalling который ссылается сама
EXPORT_API Table* OpenTableExport();
где таблица является структурой вида:
typedef struct Table
{
int fCurrKey;
int fTableNo;
int fRecSize;
char fCreating;
Table* fNextTable;
Table* fPrevTable;
MyFileType fFile;
} Table;
Итак, PInvoke этой функции от управляемого кода Я, естественно, пробовал следующее:
[DllImport("Export.dll", EntryPoint = "OpenTableExport", CharSet = CharSet.Auto, CallingConvention = CallingConvention.Cdecl)]
public static extern Table OpenTable();
С следующим классом таблиц:
[StructLayout(LayoutKind.Sequential, CharSet = CharSet.Auto)]
public class Table
{
public KeyDescription fCurrKey;
public int fTableNo;
public uint fRecSize;
public byte fCreating;
public Table fNextTable;
public Table fPrevTable;
public FileDescription fFile;
}
Теперь при использовании метода, я получаю следующее исключение (в переводе с немецкого):
Поле «fNextTable» типа «Таблица» не могут быть ранжированы, никакой поддержки сортировочной не существует для этого тип.
Почему не может .NET marshall члены fNextTable и fPrevTable того же типа, которые он сортирует в любом случае?
Я также могу просто заменить ссылки в определении управляемого класса с помощью IntPtr ... но действительно ли это необходимо? (Маршаллинг тогда будет работать более или менее).
Вам необходимо определить поля таблицы * как IntPtr. –
Ну, хорошо, я видел эту возможность, я просто не понимаю, почему это необходимо (объект, содержащий эти поля, правильно упорядочен) – Daniel
Когда вы определяете поле как таблицу, вы запрашиваете сортировку другой структуры таблицы, которая создает бесконечные рекурсии. IntPtr - это просто указатель, вы его получите, а затем переходите к другому API, ожидающему Table *, или используйте методы маршала для работы с неуправляемой памятью, например PtrToStructure. –