From: Michael R. <mic...@gm...> - 2011-01-24 23:39:33
|
I'm using SWIG to make C# bindings that are compatible with the compact framework (WinCE). I've got most of the immediate issues worked through, but my next blocker is that some of the functions return a double. Wrappers are generated but they fail at run time because the CF framework will not marshal non-integral datatypes ( http://msdn.microsoft.com/en-us/library/aa446536.aspx). By marshalling "double" as "double *", I can make everything work. But how can i get SWIG to do this for me? An example will illustrate. Here's the offending C++ method: double getMaxMagnification() const { return m_maxMag; } SWIG generates this wrapper: 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; } which is NG because it marshalls a double return value. I manually changed this to return the double via a passed-in pointer: 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; } After making the corresponding changes (below) in the C# declaration file and Proxy class, this works as expected. ========================= Interop Declaration 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); Implementation class 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; } How can I get SWIG to do this for me? I think the tasks are: (a) change the return type of the wrapper function (only) from double to void (b) add an argument (pointer to double) to the argument list so that the wrapper can send back the value that way (c) make the interop declaration reflect the above two changes (d) make the C# wrapper invoke the new wrapper function. As always big-picture re-orientation is appreciated. |