Sergio Gómez Villamor | 1 Apr 2011 19:39
Favicon

Re: return a struct by reference without creating a handler wrapper class

OK, I will try this although I don't like it very much because if I have to allocate the string using SysAllocString, that means the allocation of the string will depend on the target language I'm compiling to.

Anyway, I will try this next week (it's my time to leave). 

Thanks very much,
Sergio


On Apr 1, 2011, at 7:26 PM, David Piepgrass wrote:

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:sgomez <at> ac.upc.edu] 

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:sgomez <at> ac.upc.edu] 
Sent: Friday, April 01, 2011 7:41 AM
To: David Piepgrass
Cc: swig-user <at> lists.sourceforge.net
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.

 

 

 

 


------------------------------------------------------------------------------
Create and publish websites with WebMatrix
Use the most popular FREE web apps or write code yourself; 
WebMatrix provides all the features you need to develop and 
publish your website. http://p.sf.net/sfu/ms-webmatrix-sf
_______________________________________________
Swig-user mailing list
Swig-user <at> lists.sourceforge.net
https://lists.sourceforge.net/lists/listinfo/swig-user
David Piepgrass | 2 Apr 2011 01:24
Favicon

Re: return a struct by reference without creating a handler wrapper class

xmlns:v="urn:schemas-microsoft-com:vml" xmlns:o="urn:schemas-microsoft-com:office:office" xmlns:w="urn:schemas-microsoft-com:office:word" xmlns:m="http://schemas.microsoft.com/office/2004/12/omml" xmlns="http://www.w3.org/TR/REC-html40">

Well, you could also allocate the string with malloc() and wrap free() with SWIG:

 

%cs_struct(void*, IntPtr)

void free(void* ptr);

 

From: Sergio Gómez Villamor [mailto:sgomez <at> ac.upc.edu]
Sent: Friday, April 01, 2011 11:39 AM
To: David Piepgrass
Cc: swig-user <at> lists.sourceforge.net
Subject: Re: [Swig-user] return a struct by reference without creating a handler wrapper class

 

OK, I will try this although I don't like it very much because if I have to allocate the string using SysAllocString, that means the allocation of the string will depend on the target language I'm compiling to.

 

Anyway, I will try this next week (it's my time to leave). 

 

Thanks very much,

Sergio

------------------------------------------------------------------------------
Create and publish websites with WebMatrix
Use the most popular FREE web apps or write code yourself; 
WebMatrix provides all the features you need to develop and 
publish your website. http://p.sf.net/sfu/ms-webmatrix-sf
_______________________________________________
Swig-user mailing list
Swig-user <at> lists.sourceforge.net
https://lists.sourceforge.net/lists/listinfo/swig-user
Sergio Gómez Villamor | 4 Apr 2011 09:27
Favicon

Re: return a struct by reference without creating a handler wrapper class

Hi David,


I prefer this approach about wrapping free, but cs_struct(void *, IntPtr) neither cs_struct(void *, System.IntPtr) didn't work. Have you tried them?



On the other side, together with the cs_struct module, you give a cs_class module to be used with a C# class instead of a C# struct. I have been testing it but I think there is an error:
- Using cs_struct, resulting wrapper function is as follows:
[DllImport("dexlib", EntryPoint="CSharp_dex_Graph_TypeData")]
public static extern bool dex_Graph_GetTypeData(HandleRef, jarg1, int jarg2, ref edu.upc.dama.dex.TypeData jarg3);
- But using cs_class, resulting wrapper function is:
[DllImport("dexlib", EntryPoint="CSharp_dex_Graph_TypeData")]
public static extern bool dex_Graph_GetTypeData(HandleRef, jarg1, int jarg2,  edu.upc.dama.dex.TypeData jarg3);

Note the difference is there is no "ref" modifier in the third argument when using cs_class. Is this an error of the cs_class module?


Thanks,
Sergio



On Apr 2, 2011, at 1:24 AM, David Piepgrass wrote:

Well, you could also allocate the string with malloc() and wrap free() with SWIG:

 

%cs_struct(void*, IntPtr)

void free(void* ptr);

 

From: Sergio Gómez Villamor [mailto:sgomez <at> ac.upc.edu] 
Sent: Friday, April 01, 2011 11:39 AM
To: David Piepgrass
Cc: swig-user <at> lists.sourceforge.net
Subject: Re: [Swig-user] return a struct by reference without creating a handler wrapper class

 

OK, I will try this although I don't like it very much because if I have to allocate the string using SysAllocString, that means the allocation of the string will depend on the target language I'm compiling to.

 

Anyway, I will try this next week (it's my time to leave). 

 

Thanks very much,

Sergio


------------------------------------------------------------------------------
Create and publish websites with WebMatrix
Use the most popular FREE web apps or write code yourself; 
WebMatrix provides all the features you need to develop and 
publish your website. http://p.sf.net/sfu/ms-webmatrix-sf
_______________________________________________
Swig-user mailing list
Swig-user <at> lists.sourceforge.net
https://lists.sourceforge.net/lists/listinfo/swig-user
David Piepgrass | 4 Apr 2011 22:45
Favicon

Re: return a struct by reference without creating a handler wrapper class

xmlns:v="urn:schemas-microsoft-com:vml" xmlns:o="urn:schemas-microsoft-com:office:office" xmlns:w="urn:schemas-microsoft-com:office:word" xmlns:m="http://schemas.microsoft.com/office/2004/12/omml" xmlns="http://www.w3.org/TR/REC-html40">

In what way doesn’t it work? I haven’t actually tried %cs_struct(void*, IntPtr), but I do use %cs_struct(HWND, IntPtr), %cs_struct(HBITMAP, IntPtr), etc.

 

It is correct that there is no “ref” on TypeData using %cs_class. TypeData is supposed to be a class, so it is already passed by reference. “ref TypeData” would correspond to CTypeData** in C++.

 

Hi David,

 

I prefer this approach about wrapping free, but cs_struct(void *, IntPtr) neither cs_struct(void *, System.IntPtr) didn't work. Have you tried them?

 

 

 

On the other side, together with the cs_struct module, you give a cs_class module to be used with a C# class instead of a C# struct. I have been testing it but I think there is an error:

- Using cs_struct, resulting wrapper function is as follows:

[DllImport("dexlib", EntryPoint="CSharp_dex_Graph_TypeData")]

public static extern bool dex_Graph_GetTypeData(HandleRef, jarg1, int jarg2, ref edu.upc.dama.dex.TypeData jarg3);

- But using cs_class, resulting wrapper function is:

[DllImport("dexlib", EntryPoint="CSharp_dex_Graph_TypeData")]

public static extern bool dex_Graph_GetTypeData(HandleRef, jarg1, int jarg2,  edu.upc.dama.dex.TypeData jarg3);

 

Note the difference is there is no "ref" modifier in the third argument when using cs_class. Is this an error of the cs_class module?

 

 

Thanks,

Sergio

 

 

 

On Apr 2, 2011, at 1:24 AM, David Piepgrass wrote:



Well, you could also allocate the string with malloc() and wrap free() with SWIG:

 

%cs_struct(void*, IntPtr)

void free(void* ptr);

 

From: Sergio Gómez Villamor [mailto:sgomez <at> ac.upc.edu] 
Sent: Friday, April 01, 2011 11:39 AM
To: David Piepgrass
Cc: swig-user <at> lists.sourceforge.net
Subject: Re: [Swig-user] return a struct by reference without creating a handler wrapper class

 

OK, I will try this although I don't like it very much because if I have to allocate the string using SysAllocString, that means the allocation of the string will depend on the target language I'm compiling to.

 

Anyway, I will try this next week (it's my time to leave). 

 

Thanks very much,

Sergio

 

------------------------------------------------------------------------------
Xperia(TM) PLAY
It's a major breakthrough. An authentic gaming
smartphone on the nation's most reliable network.
And it wants your games.
http://p.sf.net/sfu/verizon-sfdev
_______________________________________________
Swig-user mailing list
Swig-user <at> lists.sourceforge.net
https://lists.sourceforge.net/lists/listinfo/swig-user
Sergio Gómez Villamor | 5 Apr 2011 08:26
Favicon

Re: return a struct by reference without creating a handler wrapper class

When I add this to my interface file,
void free(void *)
swig generates a SWIGTYPE_p_void.cs, as expected.

But when I add this to my interface file,
%cs_struct(void *, System.IntPtr);
%ignore void *;
void free(void *ptr);
if fails as follows:

C:\Users\sgomez\swigwin-2.0.2\Examples\csharp\DEX>..\..\..\swig.exe -c++ -v -deb
ug-typemap -debug-classes -csharp -namespace edu.upc.dama dexlib.i
Language subdirectory: csharp
Search paths:
   .\
   .\swig_lib\csharp\
   C:\Users\sgomez\swigwin-2.0.2\Lib\csharp\
   \csharp\
   .\swig_lib\
   C:\Users\sgomez\swigwin-2.0.2\Lib\
   \
Preprocessing...
Starting language-specific parse...
dexlib.i(36) : Error: Syntax error in input(1).

Line 36 corresponds to the cs_struct(void *, IntPtr) line. I've been looking for a kind of parse debug option for the swig command line but I haven't found it, so I have no more information about what is going wrong. Of course, "cs_struct.i" has been included (in fact, I have previous use of cs_struct working properly).


Also, I have tested your HWND use case:
%cs_struct(HWND, IntPtr);
HWND GetConsoleHwnd(void);
and it works:
  [DllImport("dexlib", EntryPoint="CSharp_GetConsoleHwnd")]
  public static extern  IntPtr  GetConsoleHwnd();


And If I do something like that:
typedef void * voidPtr;
%cs_struct(voidPtr, IntPtr);
void MyFree(voidPtr ptr)
{
free(ptr);
}
it also works. 

So I asked if you have tested cs_struct with void * before. Anyway, I could manage it using this typedef but maybe you know a clever way to get void * working with cs_struct. 




Regarding to my cs_struct/cs_class problem I solved it.



Thanks a lot once again,
Sergio


On Apr 4, 2011, at 10:45 PM, David Piepgrass wrote:

In what way doesn’t it work? I haven’t actually tried %cs_struct(void*, IntPtr), but I do use %cs_struct(HWND, IntPtr), %cs_struct(HBITMAP, IntPtr), etc.

 

It is correct that there is no “ref” on TypeData using %cs_class. TypeData is supposed to be a class, so it is already passed by reference. “ref TypeData” would correspond to CTypeData** in C++.

 

Hi David,

 

I prefer this approach about wrapping free, but cs_struct(void *, IntPtr) neither cs_struct(void *, System.IntPtr) didn't work. Have you tried them?

 

 

 

On the other side, together with the cs_struct module, you give a cs_class module to be used with a C# class instead of a C# struct. I have been testing it but I think there is an error:

- Using cs_struct, resulting wrapper function is as follows:

[DllImport("dexlib", EntryPoint="CSharp_dex_Graph_TypeData")]

public static extern bool dex_Graph_GetTypeData(HandleRef, jarg1, int jarg2, ref edu.upc.dama.dex.TypeData jarg3);

- But using cs_class, resulting wrapper function is:

[DllImport("dexlib", EntryPoint="CSharp_dex_Graph_TypeData")]

public static extern bool dex_Graph_GetTypeData(HandleRef, jarg1, int jarg2,  edu.upc.dama.dex.TypeData jarg3);

 

Note the difference is there is no "ref" modifier in the third argument when using cs_class. Is this an error of the cs_class module?

 

 

Thanks,

Sergio

 

 

 

On Apr 2, 2011, at 1:24 AM, David Piepgrass wrote:



Well, you could also allocate the string with malloc() and wrap free() with SWIG:

 

%cs_struct(void*, IntPtr)

void free(void* ptr);

 

From: Sergio Gómez Villamor [mailto:sgomez <at> ac.upc.edu] 
Sent: Friday, April 01, 2011 11:39 AM
To: David Piepgrass
Cc: swig-user <at> lists.sourceforge.net
Subject: Re: [Swig-user] return a struct by reference without creating a handler wrapper class

 

OK, I will try this although I don't like it very much because if I have to allocate the string using SysAllocString, that means the allocation of the string will depend on the target language I'm compiling to.

 

Anyway, I will try this next week (it's my time to leave). 

 

Thanks very much,

Sergio

 


------------------------------------------------------------------------------
Xperia(TM) PLAY
It's a major breakthrough. An authentic gaming
smartphone on the nation's most reliable network.
And it wants your games.
http://p.sf.net/sfu/verizon-sfdev
_______________________________________________
Swig-user mailing list
Swig-user <at> lists.sourceforge.net
https://lists.sourceforge.net/lists/listinfo/swig-user

Gmane