From: David P. <dpi...@me...> - 2007-10-30 22:53:08
|
At the beginning of October there was a discussion about how to return a std::wstring from a synthetic attribute. The problem was that SWIG assumed the attribute was a reference when it wasn't. For example: %attribute(Foo, std::wstring, FileName, GetFileName); %inline %{ #include <string> class Foo { public: std::wstring GetFileName() { return L"file.txt"; } }; %} SWIG generates this code that doesn't work because it treats FileName as a reference when it isn't: SWIGEXPORT void * SWIGSTDCALL CSharp_Foo_FileName_get(void * jarg1) { void * jresult ; Foo *arg1 =3D (Foo *) 0 ; std::wstring *result =3D 0 ; =20 arg1 =3D (Foo *)jarg1;=20 { std::wstring const &_result_ref =3D Foo_FileName_get(arg1); result =3D (std::wstring *) &_result_ref; } jresult =3D SWIG_csharp_wstring_callback(result->c_str());=20 return jresult; } William came up with a solution involving allocating a temporary copy of the string on the heap--needed only because there was no way to tell SWIG that the return value was a value, not a reference. Well, today I have the opposite problem. The .NET Compact Framework's P/Invoke system is impoverished and does not allow a 'double' or 'float' to be returned from a function. Consequently, it is only possible to return a pointer to the value, and I'm pretty sure I could extract the value from the pointer when it arrives in C#. For example, let's say I want SWIG to wrap this class: %inline %{ struct PointF { float X; float Y; }; %} I have changed the typemaps so that the value given to CSharp_PointF_X_set can be passed by reference. But it appears there's no way to do the same for CSharp_PointF_X_get, because SWIG always treats float as a value: SWIGEXPORT float SWIGSTDCALL CSharp_PointF_X_get(void * jarg1) { float jresult ; PointF *arg1 =3D (PointF *) 0 ; float result; =20 arg1 =3D (PointF *)jarg1;=20 result =3D (float) ((arg1)->X); jresult =3D result;=20 return jresult; } AFAIK, no typemap or feature can affect how X is accessed, or the cast that happens afterward, or the type of the result variable. Thus, a pointer to X is currently impossible to obtain. So, I'd like to suggest that there should be a way to control whether SWIG treats return values as references or values. But I'm not sure about how it ought to work. Can anyone offer thoughts? - David |