From: Michael R. <mic...@gm...> - 2011-01-26 00:28:13
|
Wow. This is hugely helpful. David, thanks so much. It got 99% of what I had and what it couldn't get I can do without! msr On Tue, Jan 25, 2011 at 9:40 AM, David Piepgrass <dpi...@me...>wrote: > Here’s what I (used to) use for that: > > > > > //////////////////////////////////////////////////////////////////////////////// > > // 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) > > > > > > *From:* Michael Rosen [mailto:mic...@gm...] > *Sent:* Monday, January 24, 2011 4:39 PM > *To:* swi...@li... > *Subject:* [Swig-user] change SWIG wrapper-function return type > > > > 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. > |