Jim Mace | 1 May 2010 18:53

Extreme Newbie Question

Clan,

 

Can I use SWIG on Windows to create C# wrappers for a C++ API that will be used exclusively on Linux. The API uses the Linux boost, ncurses and ncurses-devel additional libraries.

 

Thanks in advance,

Jim

------------------------------------------------------------------------------
_______________________________________________
Swig-user mailing list
Swig-user <at> lists.sourceforge.net
https://lists.sourceforge.net/lists/listinfo/swig-user
Thomas Daniel | 2 May 2010 03:58
Picon
Favicon

Avoiding memory allocations

I am trying to create wrappers for a library, where all objects contain 
a single pointer:

class Pointer;

class Object{
public:
       Object foo(Object x, const char* y);
       Pointer* ptr() const {return _pointer; }
private:
      Pointer* _pointer;
};

All the methods of Object pass Object by value (which is fine, since it 
is really just a pointer) as in method 'foo'.

By default, swig creates wrappers that allocate and deallocate 
(new/delete) Object and pass around pointers to Object (which would be 
the right thing to do if Object had more data members).  For example, 
when returning result in Perl:
     ST(argvi) = SWIG_NewPointerObj((new Object(static_cast< const 
Object& >(result))), SWIGTYPE_p_Object, SWIG_POINTER_OWN | SWIG_SHADOW);

In this case, however, it isn't necessary. I am having trouble coercing 
swig to directly stick Object into the wrappers. In Perl, by hand (i.e 
using XS), I would write a typemap like this:

     sv_setref_pv( $arg, \"${ntype}\", (void*)$var.ptr() );

or, in swig:
ST(argvi) = SWIG_NewPointerObj(result.ptr())), SWIGTYPE_p_Object, 
SWIG_POINTER_OWN | SWIG_SHADOW);

and it is certainly possible to write such typemaps in swig. But the 
question is how to make swig avoid doing new and delete and passing 
around pointers to Object (which is what it does by default), instead of 
Objects themselves?

I would appreciate any help...

-ttt

------------------------------------------------------------------------------
Lakshminarayan G | 3 May 2010 07:22
Favicon

Callbacks in Python...

Hi,

Greetings!

            I am not very sure if I can use this mailing list; but I would really appreciate any details on this.

Basically, I need some help regarding a Python script where I am trying to invoke few C++ based APIs, which have been exposed/wrapped using the SWIG tool. I am facing some issues with attaching a function pointer defined in C++ header to a function defined in my Python script. Let me explain this in detail using an example:

-----------------------

1)/* C++ Header file: example.h */

 

struct cback

{

int (*ADD)(int,int);

 

};

 

------------

2)/* SWIG Interface File : example.i */

%module example

%{

#include "example.h"

%}

struct cback

{

int (*ADD)(int,int);

 

};

------------------

3) Using SWIG Tool we generate a wrapper file(attached: example_wrap.cxx) so that c++ data would be accessed in Python script. We build this wrapper to a  DLL and import in Python script

from _example import *

 

def MyAdd(a,b):

      print a+b

      return;

 

print "Sum of 2 and 3 = ",cback_ADD_set(new_cback(),MyAdd(2,3))

 

-------------------------------

 

You could notice in the above python script the way we have assigned a function pointer ‘ADD’ to a python function MyAdd. In fact the function ‘cback_ADD_set’ is auto generated by SWIG tool and made available through DLL(_example.pyd). So, I could use this function to set the function pointer.

However, I am not very sure if this is the right way to do it. Also, Python is allowing me to assign the function pointer to any Python function, irrespective of its spec. If I have some other function MySub(), I can assign to this also. Hence it would not serve my purpose. So, I would like to know if you have any idea on how to manage the function pointers kind of variables in Python? In summary, I would like to point a function pointer defined in a C++ header to my Python function.

Kindly let me know if you need any other details from my end,

 

Thanks in advance,

 

Regards,

Lakshman..!

 

Lakshminarayan G
Team Lead - Automation Team
Altair Engineering
BANGALORE

 

 

------------------------------------------------------------------------------
_______________________________________________
Swig-user mailing list
Swig-user <at> lists.sourceforge.net
https://lists.sourceforge.net/lists/listinfo/swig-user
John Pye | 3 May 2010 16:54
Favicon
Gravatar

Re: Issue with SWIG 1.3.39 "lvalue required as unary ‘&’ operand"

Hi William, and all,

I first reported a problem SWIG 1.3.39 last year (see below), but we're 
still having problems SWIG 1.3.40 in latest Ubuntu 10.04, so I've tried 
to work out what's going on in a bit more detail. We're getting this 
error when GCC attempts to compile our SWIG-generated code from C++ to 
Python:

g++ -o pygtk/ascpy_wrap.os -c -fPIC -DHAVE_GCCVISIBILITY -I. 
-I/usr/include/python2.6 pygtk/ascpy_wrap.cc
pygtk/ascpy_wrap.cc: In function ‘PyObject* 
_wrap_Relation_getResidual(PyObject*, PyObject*)’:
pygtk/ascpy_wrap.cc:50754: error: lvalue required as unary ‘&’ operand
scons: *** [pygtk/ascpy_wrap.os] Error 1

The problem comes from code

     double Relation::getResidual() const;

which is resulting in SWIG-generated code

       result = (double *)&(arg1)->getResidual(); /* THIS LINE PRODUCES THE ERROR */

How can a function that returns a double be treated as though it returns 
a pointer to a double? Definitely looks like a bug in SWIG to me.

I tried to produce a simpler test case (attached), but the resulting 
generated code, which gave no error, was instead

    result = (double)((Relation const *)arg1)->getResidual(); /* NO ERROR IN THIS CASE */

The only clue I have managed to find on this error was a web forum 
discussion that pointed out that the '&' operator works significantly 
differently in C versus C++, something to do with lvalues and rvalues 
which I don't entirely understand.

My attempted test case is attached; the code that produces the error is 
much larger and comes from the current ASCEND subversion repo, I'll 
happily send details to anyone who would like to look at this problem in 
more detail.

Please help! SWIG 1.3.40 is now part of Ubuntu 10.04 and we really need 
to identify a solution to our problem before large numbers of people 
migrate to the new release.

Many thanks

Cheers
JP

On 20/06/09 10:37, William S Fulton wrote:
> Can you provide a small test case demonstrating the bug. Not many 
> people here are prepared to download and debug other people's large 
> projects.
>
> William
>
> John Pye wrote:
>> Hi all
>>
>> Does anyone have any thoughts on this issue with SWIG 1.3.39? It looks
>> like a regression to me, but I'd really appreciate a second opinion.
>>
>> https://ascendbugs.cheme.cmu.edu/view.php?id=403
>>
>>
>> Cheers
>> JP
>>
>> John Pye wrote:
>>> Hi all
>>>
>>> We're getting a strange error from SWIG 1.3.39 when compiling our
>>> project's code on a new Fedora 11 install. We have previously had no
>>> problems with SWIG 1.3.36 on Ubuntu 9.04.
>>>
>>> The error message comes from g++ while compiling the SWIG output:
>>>
>>> swig -o pygtk/ascpy_wrap.cc -python -c++ -O -I/usr/include/graphviz
>>> pygtk/ascpy.i
>>> g++ -o pygtk/ascpy_wrap.os -c -fPIC -DHAVE_GCCVISIBILITY -I.
>>> -I/usr/include/python2.6 pygtk/ascpy_wrap.cc
>>> pygtk/ascpy_wrap.cc: In function ‘PyObject*
>>> _wrap_Relation_getResidual(PyObject*, PyObject*)’:
>>> pygtk/ascpy_wrap.cc:50451: error: lvalue required as unary ‘&’ operand
>>> scons: *** [pygtk/ascpy_wrap.os] Error 1
>>>
>>> Can anyone give me any pointers how to fix this error? Is it a SWIG 
>>> bug,
>>> perhaps? I checked the release summaries, and there is nothing there to
>>> suggest new API rules, AFAICT.
>>>
>>> Details for reproducing the error are here:
>>> https://ascendbugs.cheme.cmu.edu/view.php?id=403
>>>
>>> Cheers
>>> JP
>>>
>> _______________________________________________
>> Swig-user mailing list
>> Swig-user <at> lists.sourceforge.net
>> https://lists.sourceforge.net/lists/listinfo/swig-user
>


env = Environment()

import distutils.sysconfig

obj = SharedObject('swigbug',['swigbug.i']
	, SWIGFLAGS = ['-python', '-c++']
	, CPPPATH = [distutils.sysconfig.get_python_inc()]
)

env.Depends('swigbug_wrap.cc','swigbug.h')
Attachment (swigbug.h): text/x-chdr, 288 bytes
%module(directors=1) swigbug

%include <python/std_string.i>
%include <python/std_except.i>
%include <python/std_vector.i>
%include <python/std_map.i>
%include <python/std_set.i>

%{
#include "swigbug.h"
%}

// All STL runtime_errors caught to Python

%exception {
	try {
		$action
	}
	catch (std::range_error &e) {
		SWIG_exception(SWIG_IndexError,e.what());
	}
	catch (std::runtime_error &e) {
		SWIG_exception(SWIG_RuntimeError,e.what());
	}
}

%include "swigbug.h"

------------------------------------------------------------------------------
_______________________________________________
Swig-user mailing list
Swig-user <at> lists.sourceforge.net
https://lists.sourceforge.net/lists/listinfo/swig-user
Bob Hood | 3 May 2010 17:38
Picon
Gravatar

Fun with %rename

I'm wrapping an API using Python 1.3.40, and I have some rather strange
behavior happening with %rename.

I have a non-template class called CompactIndexArray (although two of
the class's constructors are parameterized; whether or not that makes a
difference to this issue, I don't know).  In another header
(VertexArray.h), there is a simple, one-line typedef of
CompactIndexArray into another name, VertexArray:

    typedef CompactIndexArray VertexArray;

Now, in my Python interface file, I issue a %rename prior to the
inclusion of the headers (CompactIndexArray.h and VertexArray.h) that
looks like this:

    %rename(VertexArray) CompactIndexArray;

Doing this promotes VertexArray to a first-class citizen within the
wrapper code, making it possible to directly instantiate an instance of
VertexArray in the target language (Python), thus:

    pv = VertexArray(4)

If I omit the %rename, then VertexArray becomes a type unknown to the
target language.  Although it is referenced internally within the
wrapper code, it no longer has its own support functions (e.g.,
new_VertexArray()) that exposes it directly.

Lastly, I have a class method being wrapped that takes a VertexArray
argument:

    poly_index create_poly_directly(VertexArray& vertices);

Now, here's the strange part.  With %rename in place, creating a new
"VertexArray(4)" generates code in the wrapper that looks like this
(note the use of the "CompactIndexArray" type to create the new object):

    SWIGINTERN PyObject *_wrap_new_VertexArray__SWIG_2(PyObject
*SWIGUNUSEDPARM(self), PyObject *args) {
      ...
      resultobj = SWIG_NewPointerObj(SWIG_as_voidptr(result),
SWIGTYPE_p_LWSDK__CompactIndexArray, SWIG_POINTER_NEW |  0 );

SWIG creates wrapper code that calls the create_poly_directly() method
containing the following line of code:

      res2 = SWIG_ConvertPtr(obj1, &argp2, SWIGTYPE_p_VertexArray,  0 );

causing a SWIG_exception_fail() call.  I'm assuming it fails because of
the difference in types.

When I omit %rename() (and VertexArray is no longer directly exposed to
the target language), SWIG continues to wrap this method as taking a
VertexArray, but I then can only create an instance of CompactIndexArray
in the target language, and create_poly_directly() still fails because
it is expecting a VertexArray!

I hope I explained this clearly (because it's confusing me).  Any sage
advice?

------------------------------------------------------------------------------
Bob Hood | 3 May 2010 18:09
Picon
Gravatar

Making Python function just like C++

I'm wrapping an API using SWIG 1.3.40.  This API defines a plug-in
architecture that I'm trying to recreate as exactly as possible in
Python.  For example, here is an excerpt from a sample plug-in code in C++:

    ...
    virtual void execute_item(const SceneItemRef& item, bool
/*reevaluating*/)
    {
        MeshRef m(item);
        if (!m.valid())
            return;

        MeshEditContext edit(m.get(), component());

        VertexArray pv(4);
        pv[0] = m->create_vertex(Vector3d(-1, 0, -1));
        pv[1] = m->create_vertex(Vector3d(-1, 0, 1));
        pv[2] = m->create_vertex(Vector3d(1, 0, 1));
        pv[3] = m->create_vertex(Vector3d(1, 0, -1));
        m->create_poly_directly(pv);
    }

    virtual void execute_scene(const TreeNodeRef& scene)
    {
        execute_item(create_scene_mesh(active_scene(), "Square"), false);
    }
    ...

So far, in Python, I have the following working (up to a point):

    ...
    def execute_item(self, scene_item, reevaluating=False):
        m = MeshRef(scene_item.component())
        if not m.valid():
            return

        edit = MeshEditContext(m.get(), IPyItemCommand.component(self))

        pv = VertexArray(4)
        pv[0] = m.create_vertex(Vector3d(-1, 0, -1))
        pv[1] = m.create_vertex(Vector3d(-1, 0, 1))
        pv[2] = m.create_vertex(Vector3d(1, 0, 1))
        pv[3] = m.create_vertex(Vector3d(1, 0, -1))
        m.create_poly_directly(pv)

    def execute_scene(self, scene):
        self.execute_item(PyAsgardLib.create_scene_mesh(scene,
"PythonSquare"));
    ...

What I'm particularly focused on in this post is the creation of the
MeshRef instance.  Each of these types ("MeshRef" and "SceneItemRef")
are constructed from a parameterized type called
"ComponentInterfaceReferenceT".  This template type provides the
following constructor that allows for the seemingly implicit conversion
between types:

    template <class OtherT>
    /*implicit*/ ComponentInterfacePtrT(const
ComponentInterfacePtrT<OtherT>& other);

whose implementation looks like:

    template <class T>
    template <class OtherT>
    ComponentInterfaceReferenceT<T>::ComponentInterfaceReferenceT(const
ComponentInterfaceReferenceT<OtherT>& other):
ComponentInterfaceReference(other.component())
    {
        init(InterfaceTypeID<T>::id());
    }

If you will note, in the Python code, I'm having to explicitly pass the
"component" element to the construction by calling the component()
method directly:

    m = MeshRef(scene_item.component())

Since SWIG seems to be very type-literal in the generated code, it's
actually doing type-to-type comparisons when I attempt to simply pass
the provided ComponentInterfaceReferenceT-derived type directly:

    m = MeshRef(scene_item)

and, of course, it is failing.

While the method of passing the component() directly works, I am
wondering if there is a way to get SWIG to generate code that would
mimic this implicit construction, so I could just pass the
ComponentInterfaceReference-derived type to MeshRef() and have the
Python code look/act just like C++, as in the last line of Python above?

(Oh, and if you plan to recommend using %implicitconv, please provide an
example that would solve this.  I've tried it, without success.)

------------------------------------------------------------------------------
John Pye | 4 May 2010 04:13
Favicon
Gravatar

Re: Callbacks in Python...

Hi Laksminarayan

I'm not sure that you can pass back Python functions to C++ in that way.
One way that does work is the SWIG 'director' functionality. There, you
define a class A with virtual methods in C++. Then, in Python, you
define class B as a subclass of A. Then, you can call other SWIG-wrapped
functions that require an instance of A and the C++ code will then be
able to make use of the results of your Python methods from class B.

There's probably an easier way... but this worked for me, and doesn't
need any hacking into internal SWIG functions.

Cheers
JP

Lakshminarayan G wrote:
>
> Hi,
>
> Greetings!
>
>             I am not very sure if I can use this mailing list; but I
> would really appreciate any details on this.
>
> Basically, I need some help regarding a Python script where I am
> trying to invoke few C++ based APIs, which have been exposed/wrapped
> using the SWIG tool. I am facing some issues with attaching a function
> pointer defined in C++ header to a function defined in my Python
> script. Let me explain this in detail using an example:
>
> -----------------------
>
> 1)/* C++ Header file: example.h */
>
>  
>
> struct cback
>
> {
>
> int (*ADD)(int,int);
>
>  
>
> };
>
>  
>
> ------------
>
> 2)/* SWIG Interface File : example.i */
>
> %module example
>
> %{
>
> #include "example.h"
>
> %}
>
> struct cback
>
> {
>
> int (*ADD)(int,int);
>
>  
>
> };
>
> ------------------
>
> 3) Using SWIG Tool we generate a wrapper file(attached:
> example_wrap.cxx) so that c++ data would be accessed in Python script.
> We build this wrapper to a  DLL and import in Python script
>
> from _example import *
>
>  
>
> def MyAdd(a,b):
>
>       print a+b
>
>       return;
>
>  
>
> print "Sum of 2 and 3 = ",*cback_ADD_set*(new_cback(),MyAdd(2,3))
>
>  
>
> -------------------------------
>
>  
>
> You could notice in the above python script the way we have assigned a
> function pointer ‘ADD’ to a python function MyAdd. In fact the
> function ‘*cback_ADD_set*’ is auto generated by SWIG tool and made
> available through DLL(_example.pyd). So, I could use this function to
> set the function pointer.
>
> However, I am not very sure if this is the right way to do it. Also,
> Python is allowing me to assign the function pointer to any Python
> function, irrespective of its spec. If I have some other function
> MySub(), I can assign to this also. Hence it would not serve my
> purpose. So, I would like to know if you have any idea on how to
> manage the function pointers kind of variables in Python? In summary,
> I would like to point a function pointer defined in a C++ header to my
> Python function.
>
> Kindly let me know if you need any other details from my end,
>
>  
>
> Thanks in advance,
>
>  
>
> Regards,
>
> Lakshman..!
>
>  
>
> Lakshminarayan G
> //Team Lead - Automation Team//
> Altair Engineering
> BANGALORE
>
>  
>
>  
>
> ------------------------------------------------------------------------
>
> ------------------------------------------------------------------------------
>   
> ------------------------------------------------------------------------
>
> _______________________________________________
> Swig-user mailing list
> Swig-user <at> lists.sourceforge.net
> https://lists.sourceforge.net/lists/listinfo/swig-user
>   

------------------------------------------------------------------------------
_______________________________________________
Swig-user mailing list
Swig-user <at> lists.sourceforge.net
https://lists.sourceforge.net/lists/listinfo/swig-user
Lakshminarayan G | 4 May 2010 04:51
Favicon

Re: Callbacks in Python...

Hi JP,
   Thanks for the quick response. However, I have a difficulty with your
suggested approach which demands me to modify my C++ based library.
Unfortunately, I can not update the library, I can just use it.  
	Do you by any chance mean that, we could still add the class A
additionally without the need for modifying my library headers? Kindly
let me know...

Regards,
Lakshman..!

-----Original Message-----
From: John Pye [mailto:john <at> curioussymbols.com] 
Sent: Tuesday, May 04, 2010 7:44 AM
To: Lakshminarayan G
Cc: swig-user <at> lists.sourceforge.net
Subject: Re: [Swig-user] Callbacks in Python...

Hi Laksminarayan

I'm not sure that you can pass back Python functions to C++ in that way.
One way that does work is the SWIG 'director' functionality. There, you
define a class A with virtual methods in C++. Then, in Python, you
define class B as a subclass of A. Then, you can call other SWIG-wrapped
functions that require an instance of A and the C++ code will then be
able to make use of the results of your Python methods from class B.

There's probably an easier way... but this worked for me, and doesn't
need any hacking into internal SWIG functions.

Cheers
JP

Lakshminarayan G wrote:
>
> Hi,
>
> Greetings!
>
>             I am not very sure if I can use this mailing list; but I
> would really appreciate any details on this.
>
> Basically, I need some help regarding a Python script where I am
> trying to invoke few C++ based APIs, which have been exposed/wrapped
> using the SWIG tool. I am facing some issues with attaching a function
> pointer defined in C++ header to a function defined in my Python
> script. Let me explain this in detail using an example:
>
> -----------------------
>
> 1)/* C++ Header file: example.h */
>
>  
>
> struct cback
>
> {
>
> int (*ADD)(int,int);
>
>  
>
> };
>
>  
>
> ------------
>
> 2)/* SWIG Interface File : example.i */
>
> %module example
>
> %{
>
> #include "example.h"
>
> %}
>
> struct cback
>
> {
>
> int (*ADD)(int,int);
>
>  
>
> };
>
> ------------------
>
> 3) Using SWIG Tool we generate a wrapper file(attached:
> example_wrap.cxx) so that c++ data would be accessed in Python script.
> We build this wrapper to a  DLL and import in Python script
>
> from _example import *
>
>  
>
> def MyAdd(a,b):
>
>       print a+b
>
>       return;
>
>  
>
> print "Sum of 2 and 3 = ",*cback_ADD_set*(new_cback(),MyAdd(2,3))
>
>  
>
> -------------------------------
>
>  
>
> You could notice in the above python script the way we have assigned a
> function pointer 'ADD' to a python function MyAdd. In fact the
> function '*cback_ADD_set*' is auto generated by SWIG tool and made
> available through DLL(_example.pyd). So, I could use this function to
> set the function pointer.
>
> However, I am not very sure if this is the right way to do it. Also,
> Python is allowing me to assign the function pointer to any Python
> function, irrespective of its spec. If I have some other function
> MySub(), I can assign to this also. Hence it would not serve my
> purpose. So, I would like to know if you have any idea on how to
> manage the function pointers kind of variables in Python? In summary,
> I would like to point a function pointer defined in a C++ header to my
> Python function.
>
> Kindly let me know if you need any other details from my end,
>
>  
>
> Thanks in advance,
>
>  
>
> Regards,
>
> Lakshman..!
>
>  
>
> Lakshminarayan G
> //Team Lead - Automation Team//
> Altair Engineering
> BANGALORE
>
>  
>
>  
>
>
------------------------------------------------------------------------
>
>
------------------------------------------------------------------------
------
>   
>
------------------------------------------------------------------------
>
> _______________________________________________
> Swig-user mailing list
> Swig-user <at> lists.sourceforge.net
> https://lists.sourceforge.net/lists/listinfo/swig-user
>   

------------------------------------------------------------------------------
aisha | 4 May 2010 07:29
Picon
Favicon

download std_list.i for java?

Hi,

Does anyone know where I can download  "std_list.i"  for converting a 
C++ program to Java? Currently I get the unable to find  std_list.i error.

Thanks!

------------------------------------------------------------------------------
hawks21 | 4 May 2010 09:16
Picon
Favicon

dlopen fails but symbol is on dynamic-load path (according to nm)


Hi,
I'm trying a python swig of a simple function that includes an object from
an external library (Magick++).

The build (compile & swig) goes fine, but when I try to access it from
python, I get

ImportError: dlopen(BLAH/magick-swig/_mymodule.so, 2): Symbol not found:
__ZN6Magick5ImageC1Ev
  Referenced from: BLAH/magick-swig/_mymodule.so
  Expected in: dynamic lookup

This happens despite the fact that the proper dylib (libMagick++.dylib) is
copied into the local folder (and the local path is on DYLD_LIBRARY_PATH for
good measure), and when I run:
nm libMagick++.dylib

... it lists the exact symbol that's "not found" (__ZN6Magick5ImageC1Ev). 
Clearly I'm not understanding something about nm and/or dynamic linking,
perhaps this is a basic question.

Any help greatly appreciated.  I can provide any details if the answer
doesn't jump out at people.  This is Mac leopard.

Thanks.
--

-- 
View this message in context: http://old.nabble.com/dlopen-fails-but-symbol-is-on-dynamic-load-path-%28according-to-nm%29-tp28344649p28344649.html
Sent from the swig-user mailing list archive at Nabble.com.

------------------------------------------------------------------------------

Gmane