2011-04-05 26 views
2

由SWIG包裝的C++對象在C++和Python之間來回傳遞自定義Python數據時,是否有辦法使用它們?例如:在SWIG中攜帶自定義Python數據的C++對象

example.h文件

class MyClass 
{ 
public: 
    int foo; 
}; 

// Black box functions. 
// Only thing guaranteed is that the last object handed to consume 
// will be returned by eject. 
void consume(MyClass *obj); 
MyClass *eject(); 

example.i

%module Example 

%{ 
     #include "example.h" 
%} 

%include "example.h" 

test.py

import Example 

a = Example.MyClass() 
a.bar = "Puppies" 

Example.consume(a) 
b = Example.eject() 

## Should output "Puppies" 
print b.bar 

的電流輸出是一個n「AttributeError:bar」。

有沒有辦法獲得這種功能?如果SWIG的__ getattr _可以自定義MyClass的函數,那麼可能存儲未知屬性並從內部PyObject *加載(通過自動使SWIG子類MyClass或通過在MyClass中存在此類對象)?

謝謝!

回答

0

這是唯一的(部分)解決方案,我想出迄今:

class MyClass 
{ 
... 
MyClass() : data(NULL) {} 
~MyClass() {if(data) Py_DECREF(data);} 
PyObject *data; 
}; 


%typemap(in) PyObject* data { 
    if(arg1 && arg1->data != NULL) 
     Py_DECREF(arg1->data); 
    $1 = $input; 
    Py_XINCREF($1); 
} 

%typemap(out) PyObject* data { 
    $result = $1; 
} 

問題

1)痛飲設置$1NULL,而不是現有的值,而且我無法找到官方的方式來訪問類型映射中的現有值。以上取決於SWIG將對象(MyClass *)命名爲arg1。有用,但可能不適用於未來的SWIG版本。

2)Python代碼必須是a.data.bar = "Puppies"。這沒關係,但並不完美。

3)它要求該班級有一個data成員。這對我目前的需求是可以的,並且可以由基類來處理。

4)該類的析構函數還必須知道數據並進行清理。再次,對於我目前的需求還好,但有點麻煩。