我正在使用SWIG制作与紧凑框架(WinCE)兼容的C#绑定。我已经解决了大部分直接问题,但我的下一个阻止是某些函数返回了一个双精度函数。生成包装器但它们在运行时失败,因为CF框架不会封送非整数数据类型(http://msdn.microsoft.com/en-us/library/aa446536.aspx)
我的示例失败是尝试包装此函数:
double getMaxMagnification() const
{
return m_maxMag;
}
SWIG生成此包装器:
SWIGEXPORT double SWIGSTDCALL CSharp_LTIImageFilter_getMaxMagnification(void * jarg1) {
double jresult ;
LizardTech::LTIImageFilter *arg1 = (LizardTech::LTIImageFilter *) 0 ;
double result;
arg1 = (LizardTech::LTIImageFilter *)jarg1;
result = (double)((LizardTech::LTIImageFilter const *)arg1)->getMaxMagnification();
jresult = result;
return jresult;
}
这是NG,因为它需要编组双返回值。
我手动更改了这个以通过传入的指针返回double:
SWIGEXPORT void SWIGSTDCALL CSharp_LTIImageFilter_getMaxMagnification(void * jarg1, void *jarg2) {
fprintf(stderr, "CSharp_LTIImageFilter_getMaxMagnification\n");
//double jresult ;
LizardTech::LTIImageFilter *arg1 = (LizardTech::LTIImageFilter *) 0 ;
double result;
arg1 = (LizardTech::LTIImageFilter *)jarg1;
result = (double)((LizardTech::LTIImageFilter const *)arg1)->getMaxMagnification();
*((double*)jarg2) = result;
//jresult = result ;
//return jresult;
}
在C#声明文件和实现类中进行相应的更改后,这将按预期工作。
即,
互操作声明
NG:
[DllImport("LizardTech_SdkInterop.dll", EntryPoint="CSharp_LTIImageFilter_getMaxMagnification")]
public static extern double LTIImageFilter_getMaxMagnification(IntPtr jarg1);
行:
[DllImport("LizardTech_SdkInterop.dll", EntryPoint="CSharp_LTIImageFilter_getMaxMagnification")]
public static extern void LTIImageFilter_getMaxMagnification(IntPtr jarg1, ref double jarg2);
实施班
NG:
public override double getMaxMagnification() {
double ret = RasterSDKPINVOKE.LTIImageFilter_getMaxMagnification(swigCPtr);
return ret;
}
行:
public override double getMaxMagnification() {
double ret = 0;
RasterSDKPINVOKE.LTIImageFilter_getMaxMagnification(swigCPtr, ref ret);
return ret;
}
我如何让SWIG为我这样做?我认为任务是:
(a)将包装函数(仅)的返回类型从double更改为void (b)向参数列表添加一个参数(指向double的指针),以便包装器可以通过该方式发回值 (c)使互操作声明反映上述两个变化 (d)使C#包装器调用新的包装函数。
一如既往地重新定位大画面。
答案 0 :(得分:1)
我非常感谢David Piepgrass。它并不完美,但对我来说已经足够了。
http://sourceforge.net/mailarchive/message.php?msg_id=26952332
////////////////////////////////////////////////////////////////////////////////
// Floating-point value marshalling for .NET Compact Framework:
// All floating-point values must be passed by reference. MULTITHREADING DANGER:
// For return values a pointer to a static variable is returned.
%define %cs_compact_framework_float(FLOAT)
%typemap(ctype, out="FLOAT*") FLOAT "FLOAT*"
%typemap(ctype, out="FLOAT*") FLOAT*, FLOAT&, const FLOAT& "FLOAT*"
%typemap(imtype, out="IntPtr") FLOAT, FLOAT*, FLOAT&, const FLOAT& "ref FLOAT"
%typemap(cstype, out="FLOAT") FLOAT, const FLOAT& "FLOAT"
%typemap(cstype, out="FLOAT") FLOAT*, FLOAT& "ref FLOAT"
%typemap(in) FLOAT %{ $1 = *$input; %}
%typemap(in) FLOAT*, FLOAT&, const FLOAT& %{ $1 = $input; %}
%typemap(out, null="NULL") FLOAT, FLOAT*, FLOAT&, const FLOAT& %{
// Not thread safe! FLOAT must be returned as a pointer in Compact Framework
static FLOAT out_temp;
out_temp = $1;
$result = &out_temp;
%}
%typemap(csin) FLOAT, const FLOAT& "ref $csinput"
%typemap(csin) FLOAT*, FLOAT& "ref $csinput"
%typemap(csout, excode=SWIGEXCODE) FLOAT, FLOAT*, FLOAT&, const FLOAT& {
IntPtr ptr = $imcall;$excode
FLOAT ret = (FLOAT)Marshal.PtrToStructure(ptr, typeof(FLOAT));
return ret;
}
%typemap(csvarout, excode=SWIGEXCODE2) FLOAT, FLOAT*, FLOAT&, const FLOAT&
%{
get {
IntPtr ptr = $imcall;$excode
FLOAT ret = (FLOAT)Marshal.PtrToStructure(ptr, typeof(FLOAT));
return ret;
}
%}
%enddef
%cs_compact_framework_float(float)
%cs_compact_framework_float(double)