문제

This could be something simple I'm missing but I can't find any explanation.

Given an abstract class, which is implemented elsewhere and its interface provided by an exported function:

class IFoo {
public:
    virtual ~IFoo(){}
    virtual void bar()=0;
};

extern IFoo* get_interface();

In c++ I would use this as:

IFoo* foo = get_interface();
foo->bar();

If I SWIG this, I can import the module and assign get_interface() to a variable:

import myfoo
foo = myfoo.get_interface()

But I can't access foo.bar():

>>> foo.bar()
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
AttributeError: 'SwigPyObject' object has no attribute 'bar'

What am I missing?

Thanks!


Here is the full thing if the fragments above aren't clear enough:

The *.i file:

%module myfoo
#define SWIG_FILE_WITH_INIT

%include "myfoo.h"
%{
#include "myfoo.h"
%}

The myfoo.h header:

class IFoo {
public:
    virtual ~IFoo(){}
    virtual void bar()=0;
    virtual void release()=0;
};

extern IFoo* get_interface();

The implementation file (myfoo.cpp)

#include "myfoo.h"
#include <iostream>

class Foo : public IFoo {
public:
    Foo(){}
    ~Foo(){}
    void bar();
    void release();
};

void Foo::bar() {
    cout << "Foo::bar()..." << endl;
}

void Foo::release() {
    delete this:
}

IFoo* get_interface() {
    return new Foo();
}
도움이 되었습니까?

해결책

I found the problem. I had this within a build system generating a Ruby extension. When I decided to add Python bindings, I just added a new (Xcode) target generating it just as I was doing for the Ruby extension. What I didn't realize was that swig also generates a module.py file with all the initialization code (unlike Ruby). Once I found that, I simply moved the generated python file along with the extension dynamic library file and imported it instead. It all works now.

I found that by actually creating the above myfoo code by hand (as opposed to running my build system, which ignored the extra myfoo.py file alltogether). Once I run swig by hand, I noticed it generated not only myfoo_wrapp.cpp but also myfoo.py.

Thanks for the effort. For future reference, this has nothing to do with directors (I'm not trying to create a two-way interface). It was simply not knowing about the extra python initialization code generated by swig.

Before:

myfoo.i
myfoo.h
myfoo.cpp

>swig -c++ -python myfoo.i

After:

myfoo.i
myfoo.h
myfoo.cpp
myfoo.py    <== Missed this one
myfoo_wrap.cxx

다른 팁

Check that you have "directors" turned on in your .i file for your module:

%module(directors="1") myfoo

This is discussed in section 34.5 "Cross language polymorphism" of SWIG docs. If it is already on, put a comment and I will take a closer look.

라이센스 : CC-BY-SA ~와 함께 속성
제휴하지 않습니다 StackOverflow
scroll top