简体   繁体   中英

Calling SWIG generated code from Python interpreter

I am trying to use SWIG in an effort to call member functions of a C++ object from Python. Currently I have a small example class with a getter and setter to modify a member variable of the C++ class. Here is the C++ header file:

#ifndef _square_
#define _square_
#include <iostream>

class Square
{
 private:
    double x;
    double y;
    const char *name;

 public:
    void setName(const char*);
    const char* getName();
    Square() {
        name = "construct value";
    };
};
#endif

Here is the .cpp implementation file:

#include <iostream>
using namespace std;
#include "Square.h"

const char* Square::getName()
{
    return name;
}

void Square::setName(const char* name)
{
    this->name = name;
    return;
}

And the Square.i file for SWIG:

%module Square
%{
#include "Square.h"
%}

%include "Square.h"

SWIG seems to generate the Square_wrap.cxx file without issue, and the resulting object files seem to link fine:

$ swig -python -c++ Square.i
$ g++ -c -fpic Square.cxx Square_wrap.cxx -I/usr/include/python2.7
$ g++ -shared Square.o Square_wrap.o -o _Square.so

Now for some example Python to test the results:

$ cat test2.py
#!/usr/bin/python
import Square

s = Square.Square()

print s.getName()
s.setName("newnametest")
print s.getName()

If I run this through the Python interpreter everything works fine:

$ python test2.py
construct value
newnametest

But if I interactively enter in the test lines via Python's CLI, things do not work:

$ python
Python 2.7.4 (default, Apr 19 2013, 18:28:01) 
[GCC 4.7.3] on linux2
Type "help", "copyright", "credits" or "license" for more information.
>>> import Square
>>> 
>>> s = Square.Square()
>>> 
>>> print s.getName()
construct value
>>> s.setName("newnametest")
>>> print s.getName()

>>> s.getName()
'<stdin>'
>>> s.setName('newnametest')
>>> s.getName()
''
>>> s.setName("newnametest")
>>> s.getName()
''

Does Python handle a Python script file differently under the hood in comparison to the CLI, or am I somehow abusing the Python interface generated by SWIG? Any tips on how to debug or understand the issue under the hood would be much appreciated.

As far as I see, you are just storing the reference on the cpp file ( this->name = name ). It would be good to copy it, because there are high chances the string doesn't last enough and is just discarded after the function returns (and garbage collected slightly after that). This would explain why in the script it works (there is no GCollection nor anything else happens between the two calls).

Try making a copy with strdup or using std::string .

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM