我有一些旧代码想移植到C#中。我不能修改C++代码,我只需要处理我得到的内容即可。

所以,情况。我正在使用SwIG,遇到了以下功能:

void MarshalMe(int iNum, FooClass** ioFooClassArray);

如果对此进行SWIG操作,它将不知道如何处理数组,因此它将创建SWIGTYPE_p_pFooClass。很公平!
C#代码看起来像
void MarshalMe(int iNum, SWIGTYPE_p_p_FooClass ioFooClassArray); // Not ideal!

有一些技巧可以正确编码此类代码,因此我尝试了其中的一些技巧:
%typemap(ctype)   FooClass** "FooClass**"
%typemap(cstype)  FooClass** "FooClass[]"
%typemap(imtype, inattributes="[In, Out, MarshalAs(UnmanagedType.LPArray)]") FooClass** "FooClass[]"
%typemap(csin)    FooClass** "$csinput"
%typemap(in)      FooClass** "$1 = $input;"
%typemap(freearg) FooClass** ""
%typemap(argout)  FooClass** ""

这有效地创建了更好的签名:
void MarshalMe(int iNum, FooClass[] ioFooClassArray); // Looks good! Would it work?

但是,当我尝试运行它时,出现以下错误:
{"Exception of type 'System.ExecutionEngineException' was thrown."}

关于实际的类型图有什么想法吗?

最佳答案

异常告诉您该函数已损坏垃圾回收堆。它写到数组末尾。如果实际上是FooClass []这个大问题,那么您必须首先创建数组:

 FooClass[] array = new FooClass[666];
 MarshalMe(42, array);

假设函数将用FooClass对象填充数组。数组的大小在这里确实很重要,您必须对将要返回的元素数有所了解。仅当“iNum”是表明数组有多长的参数时,这才可以可靠地工作。传递数组长度

这也可能意味着该函数将自己创建数组并返回指向它的指针。如果真是这样,您真是一团糟,无法释放该阵列的内存。

10-07 22:16