参考自己的编组类型

时间:2014-07-31 06:36:07

标签: c# c pinvoke marshalling

我的c ++代码中有以下(缩短的)函数定义:

EXPORT_API Table* OpenTableExport();

其中Table是表单的结构:

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无法在任何情况下对编组所使用的相同类型的fNextTable和fPrevTable成员进行编组操作?

我也可以用IntPtr替换托管类定义中的引用...但这是否真的有必要? (然后编组会或多或少地起作用)。

1 个答案:

答案 0 :(得分:1)

通过以下方式定义结构:

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

测试IntPtr成员的NULL(IntPtr.Zero)并处理它们。可能非托管API包含期望Table*的其他函数。另请参阅Marshal.PtrToStructure方法和托管非托管内存交换的其他低级Marshal方法。