2011-01-22 87 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)