Re: C++ to Python and returning members of a C++ object

Terry Barnaby <[email protected]>
Newsgroups gmane.comp.programming.swig
Message-ID <[email protected]>
Hi Jake,

Ah, just worked it out. You must be using the swig "-builtin" option. I 
have modified the code to use "self" in that case.
Next item: I need to try and workout how not to call 
SwigContainerReference() when returning base types such as int for 
efficiency.

Terry
On 23/09/2020 07:34, Terry Barnaby wrote:
> Hi Jake,
>
> Ok, I will look at doing a pull once it is in a state to do so.
>
> I was intending to only use the reference counting system for member 
> gets for now and only when the containerReference feature is enabled 
> so it won't affect any other code (apart from the slight increase in 
> memory usage).
> However, I can look at using if for the reference counting in your 
> container code if people think it is worth going further with it ?
>
> I'm not sure on your self vs args change, I am missing something here, 
> are you using some particular swig "features" when generating the 
> wrapper? A typical *_get function on my wrapper looks like it needs 
> the args, the code looks like:
>> SWIGINTERN PyObject *_wrap_ClassB_b_get(PyObject 
>> *SWIGUNUSEDPARM(self), PyObject *args) {
>>   PyObject *resultobj = 0;
>>   ClassB *arg1 = (ClassB *) 0 ;
>>   void *argp1 = 0 ;
>>   int res1 = 0 ;
>>   PyObject *swig_obj[1] ;
>>   ClassA *result = 0 ;
>>
>>   if (!args) SWIG_fail;
>>   swig_obj[0] = args;
>>   res1 = SWIG_ConvertPtr(swig_obj[0], &argp1,SWIGTYPE_p_ClassB, 0 |  0 );
>>   if (!SWIG_IsOK(res1)) {
>>     SWIG_exception_fail(SWIG_ArgError(res1), "in method '" 
>> "ClassB_b_get" "', argument " "1"" of type '" "ClassB *""'");
>>   }
>>   arg1 = reinterpret_cast< ClassB * >(argp1);
>>   result = (ClassA *)& ((arg1)->b);
>>   resultobj = SWIG_NewPointerObj(SWIG_as_voidptr(result), 
>> SWIGTYPE_p_ClassA, 0 |  0 );
>>   SwigContainerReference(args, resultobj); // Increment reference 
>> count of the container object and add a pointer to the container to 
>> this in the returned object
>>   return resultobj;
>> fail:
>>   return NULL;
>> }
> My current patch and example is attached.
>
> Terry
> On 22/09/2020 21:49, Jake wrote:
>> Terry,
>>
>> You should open a pull request on Github with your proposed change.  
>> William or another maintainer will have to accept it to get in.
>>
>> I'm not a maintainer, but I would recommend the following:
>>
>> Replace my implementation of the container owner function by your 
>> own, but keep the template specialization so the container code works 
>> as before.
>> In your insertion points, use swig::pointer_category as the template 
>> argument so the ref-counting specialization is called.
>>
>> Yes, I replaced 'args' with 'self' where you showed. 'self' is the 
>> wrapper for the parent instance, 'args' is a tuple of function 
>> arguments to be unpacked.
>>
>> When you have in Python:
>>
>> m = Mixed()
>> o = m.obj
>>
>> And Mixed.obj is some wrapped type (e.g. not a string or other value 
>> that gets copied), look at the generated code:
>>
>> 6903 SWIGINTERN PyObject *_wrap_Mixed_obj_get(PyObject *self, 
>> PyObject *args) {
>>
>> 6904 PyObject *resultobj = 0;
>>
>> 6905 Mixed *arg1 = (Mixed *) 0;
>>
>> 6906 void*argp1 = 0;
>>
>> 6907 intres1 = 0;
>>
>> 6908 PyObject *swig_obj[1] ;
>>
>> 6909 MyObject *result = 0;
>>
>> 6910
>>
>> 6911 if(!SWIG_Python_UnpackTuple(args, "Mixed_obj_get", 0, 0, 0)) 
>> SWIG_fail;
>>
>> 6912 res1 = SWIG_ConvertPtr(self, &argp1,SWIGTYPE_p_Mixed, 0|0);
>>
>> 6913 if(!SWIG_IsOK(res1)) {
>>
>> 6914 SWIG_exception_fail(SWIG_ArgError(res1), "in method 
>> '""Mixed_obj_get""', argument ""1"" of type '""Mixed *""'");
>>
>> 6915 }
>>
>> 6916 arg1 = reinterpret_cast< Mixed * >(argp1);
>>
>> 6917 result = (MyObject *)& ((arg1)->obj);
>>
>> 6918 resultobj = SWIG_NewPointerObj(SWIG_as_voidptr(result), 
>> SWIGTYPE_p_MyObject, 0|0);
>>
>> 6919 SwigContainerReference(args, resultobj); // Increment reference 
>> count of the container object and add a pointer to the container to 
>> this in the returned object
>>
>>
>> Without that change I was getting crashes.
>>
>> -Jake
>>
>>
>>
>> On Tue, Sep 22, 2020 at 10:28 AM Terry Barnaby <[email protected] 
>> <mailto:[email protected]>> wrote:
>>
>>     Hi Jake,
>>
>>     I have been away from this for a while with other work.
>>
>>     You stated:
>>     On 19/08/2020 09:36, Terry Barnaby wrote:
>>     > It segfaults on pointer-category objects because you should be
>>     passing
>>     > "self" as the first argument not "args", I corrected that for the
>>     > benchmarks above.
>>
>>     Not sure what you mean here, the only place I use "args " is in:
>>
>>         Printf(f->code, "SwigContainerReference(args, resultobj); //
>>     Increment reference count of the container object and add a
>>     pointer to
>>     the container to this in the returned object\n");
>>
>>     And this seems correct, certainly I can't use "self" in place of
>>     "args"
>>     here as the code won't compile. May I ask what change you made here ?
>>
>>     I'm not sure where the SWIG group want to go on this. For the
>>     projects
>>     I'm involved in I need this fix to eliminate the memory faults when
>>     returning C++ members in Python so I will be creating my own local
>>     version of SWIG, with my patch applied, for now. But I am keen to
>>     try
>>     and get something like this included in the main tree if possible.
>>
>>     Terry
>>
>

_______________________________________________
Swig-user mailing list
[email protected]
https://lists.sourceforge.net/lists/listinfo/swig-user
lmpx.com only provides a reader for public news (NNTP) servers. It is not affiliated with the servers or forums shown here and is not responsible for the content of articles, which is written by their respective authors.