Daniel
Daniel

Reputation: 411

Marshalling type which references itself

I have following (shortened) function definition in my c++ code:

EXPORT_API Table* OpenTableExport();

where Table is a struct of the form:

typedef struct Table
{
  int fCurrKey;
  int fTableNo;
  int fRecSize;
  char fCreating;
  Table* fNextTable;
  Table* fPrevTable;
  MyFileType fFile;
} Table;

So, to PInvoke this function from managed code I naturally tried following:

[DllImport("Export.dll", EntryPoint = "OpenTableExport", CharSet = CharSet.Auto,   CallingConvention = CallingConvention.Cdecl)]
public static extern Table OpenTable();

With following table class:

[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;

}

Now when using the method, I get following exception (translated from german):

The field "fNextTable" of type "Table" can not be marshalled, no marshalling support exists for this type.

Why can't .NET marshall the fNextTable and fPrevTable members of the same type it is marshalling in any case?

I can also just replace the references in the managed class definition with IntPtr... but is this really necessary? (The marshalling then will work more or less).

Upvotes: 0

Views: 108

Answers (1)

Alex F
Alex F

Reputation: 43311

Define the structure by the following way:

public class Table
{
    public KeyDescription fCurrKey;
    public int fTableNo;
    public uint fRecSize;
    public byte fCreating;
    public IntPtr fNextTable;
    public IntPtr fPrevTable;
    public FileDescription fFile;
}

Test IntPtr members for NULL (IntPtr.Zero) and handle them. Probably unmanaged API contains another functions expecting Table*. See also Marshal.PtrToStructure method and another low-level Marshal methods for managed-unmanaged memory exchange.

Upvotes: 1

Related Questions