我必须包装以下c ++函数:
class Foo {
unsigned int *getVector3();
};
成员函数getVector3
返回一个(固定的)3D数组,例如[1,2,3]
。如何将arrays_csharp.i
用作返回类型?该文档仅描述输入参数:
在我的情况下,返回类型始终是一个固定大小的数组(包含3个元素)。
答案 0 :(得分:1)
我有一个答案,尽管我认为这并不完全令人满意。不过,这主要受我对C#的了解所限制,因此您可以使它比我更好地工作。
我认为您在这里找不到arrays_csharp。看来这与固定内存有关,因此可以将其用作函数的输入,但是在您的方案中,您已经分配了要使用的内存。
使用System.InteropServices.Marshal通常很容易(对于3D矢量来说也很便宜)。因此,我根据您想要的内容整理了一些类型图:
%module test
%typemap(csout,excode=SWIGEXCODE) unsigned *getVector {
global::System.IntPtr cPtr = $imcall;$excode
int[] tmp = new int[3];
// I have no idea why Marshal.Copy does not seem to have any support for unsigned types...
global::System.Runtime.InteropServices.Marshal.Copy(cPtr, tmp, 0, 3);
// There is probably a better way to go from int[3] -> uint[3], but it is not obvious to me
return new $typemap(cstype, $*1_type)[3]{($typemap(cstype, $*1_type))tmp[0],($typemap(cstype, $*1_type))tmp[1],($typemap(cstype, $*1_type))tmp[2]};
}
%typemap(cstype) unsigned *getVector "$typemap(cstype, $*1_type)[]"
%inline %{
unsigned *getVector() {
static unsigned arr[3] = {1,2,3};
return arr;
}
%}
一些注意事项:
$typemap(cstype, $*1_type)
是一种奇特的说法,可以找到与我的C元素类型相对应的C#类型。我倾向于尝试避免在类型映射中显式地编写类型,因为这会使事情变得更加通用。Marshal.Copy
似乎只适用于有符号数组类型,而不是无符号数组类型,原因是我不太清楚。而且我看不到自动找到未签名类型的相应签名类型的方法,因此我确实必须显式编写int[]
int
的{{1}}类型的大小来解决此问题。 (例如,使用tmp
代替int64
,但这不是很漂亮)那已经足够我可以运行以下程序(使用Mono)并获得预期的输出
int32
如果有用的话,我们可以做更多的工作来使这个通用(即其他大小向量,其他数据类型public class runme {
static void Main(string[] args) {
uint[] arr = test.getVector();
System.Console.WriteLine(arr[0]);
System.Console.WriteLine(arr[1]);
System.Console.WriteLine(arr[2]);
}
}
等)。