From: David P. <dpi...@me...> - 2011-04-01 17:26:29
|
If you want to allocate the string on the C++ side and release it on the C# side, given that %cs_struct bypassed SWIG's normal wrapping, I suppose the best option is BSTRs. On the C++ side you call SysAllocString or SysAllocStringLen to create a BSTR that you put in the structure. Then in C# call Marshal.PtrToStringBSTR to convert the IntPtr (which points to the BSTR) to System.String, and finally release the string with Marshal.FreeBSTR. From: Sergio Gómez Villamor [mailto:sg...@ac...] Yes that is what I thought. Thanks for the explanation. I have tested your first suggestion and it worked, but I have a question I have this in the C# structure public struct TypeData { private int id; private IntPtr name; public int GetId() { return id; } public string GetName() { return System.Runtime.InteropServices.Marshal.PtrToStringUni(name); } } and this in the C++ structure struct TypeData { int id; const wchar_t *name; }; and I guess "IntPtr name" and "wchar_t *name" are two pointers referencing the same memory address. Since this wchar buffer should be released when the C# TypeData structure is released, how could I do that? Should I add a destructor to my C# TypeData and release from ther the "IntPtr name"? If I solve this, I promise I will stop disturbing you :-) thanks, Sergio On Apr 1, 2011, at 6:23 PM, David Piepgrass wrote: When using %cs_struct, other typemaps such as std_wstring.i will have no effect. %cs_struct causes the structure to be passed *bitwise*, and the .NET marshaler is in charge of converting your C# structure to a C++ structure or vice versa. Therefore you can't use std::string or std::wstring in your structure. You might be able to use wchar_t* in C++, and extract the string in C# using one of two methods: 1. Put "public IntPtr strPtr;" in the C# structure and use System.Runtime.InteropServices.Marshal.PtrToStringUni(strPtr); to extract the string 2. Put "[MarshalAs(UnmanagedType.LPWStr)] public string str;" in the C# structure. I haven't tried this, but if you're lucky it'll make the marshaller extract the string automatically. I don't know who on this list would be an expert in SWIG for Java and JNI. From: Sergio Gómez Villamor [mailto:sg...@ac...] Sent: Friday, April 01, 2011 7:41 AM To: David Piepgrass Cc: swi...@li...<mailto:swi...@li...> Subject: Re: [Swig-user] return a struct by reference without creating a handler wrapper class Thanks David, Starting from this simple example, I could do the same with my structure. Anyway, I have some questions? - If I use common data types into the structure (int, long, double...) I have no problems, but if I try to add an string into the struct, then it fails (AccessViolationException). I have tried "std::string" and "wchar_t *" with no success (of course I have added corresponding "std_wstring.i" or "wchar.i" to do that). Is there something I should take into account or cs_struct has not been though to do that? - cs_struct just works for C#, what about java? I remember you told me you do not know how to do this for Java. Would you tell me if there is someone else who could help me with Java? Thanks, Sergio On Mar 31, 2011, at 9:39 PM, David Piepgrass wrote: Sorry, I don't know what's wrong. I suggest that you try something simple such as this: %{ struct Point2D { int X, Y; }; %} %cs_struct(Point2D, System.Drawing.Point) %inline %{ void Test1(Point2D p) {} void Test2(Point2D& p) {} %} If Test1 and Test2 are wrapped correctly, look for the differences between this code and your code. |