我的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替换托管类定义中的引用...但这是否真的有必要? (然后编组会或多或少地起作用)。
答案 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
方法。