2011-01-22 70 views
1

我正在使用SWIG来制作与紧凑框架(WinCE)兼容的C#绑定。我已经解决了大部分的直接问题,但我的下一个拦截器是一些函数返回一个double。生成封装器,但它们在运行时失败,因为CF框架不会封送非整数数据类型(http://msdn.microsoft.com/en-us/library/aa446536.aspx)更改SWIG封装函数返回值

我的示例失败是试图包装这个功能:

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,因为它需要编组双返回值。

我手动更改这通过传入的指针返回双:

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); 

OK:

[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; 
    } 

OK:

public override double getMaxMagnification() { 
    double ret = 0; 
    RasterSDKPINVOKE.LTIImageFilter_getMaxMagnification(swigCPtr, ref ret); 
    return ret; 
    } 

我怎样才能SWIG为我做到这一点?我认为这些任务是:

(a)将包装器函数的返回类型(仅)从double更改为void (b)将参数(double指针)添加到参数列表中,以便包装器可以发送(c)使互操作声明反映上述两个变化 (d)使C#包装器调用新的包装函数。

一如既往的大图片重新定位是赞赏。

回答

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)