問題:我使用SWIG在python中包裝了一些C++代碼。在python方面,我想要一個包裝的C++指針,並將其向下轉換成一個指向子類的指針。我已經向SWIG.i文件添加了一個新的C++函數來執行這種向下轉換,但是當我從python調用它時,我得到一個TypeError。如何從Python SWIG包裝中下載C++對象?
下面是詳細信息:
我有兩個C++類,基類和派生。派生是Base的一個子類。我有第三個類Container,它包含Derived,併爲其提供訪問者。存取器返回導出一個const基地&,如圖所示:
class Container {
public:
const Base& GetBase() const {
return derived_;
}
private:
Derived derived_;
};
我使用包裹在SWIG蟒這些類。在我的python代碼中,我想將Base參考向下放到Derived。要做到這一點,我已經寫進痛飲.i文件在C++中它執行下鑄造的輔助功能:
%inline %{
Derived* CastToDerived(Base* base) {
return static_cast<Derived*>(base);
}
%}
在我的Python代碼,我稱這種向下轉換函數:
base = container.GetBase()
derived = CastToDerived(base)
當我這樣做,我得到以下錯誤:
TypeError: in method 'CastToDerived', argument 1 of type 'Base *'
爲什麼會這樣發生?
作爲參考,這裏是由SWIG生成的.cxx文件的相關位;即原有的功能,它的蟒蛇接口,指明分數分身:
Derived* CastToDerived(Base* base) {
return static_cast<Derived*>(base);
}
// (lots of other generated code omitted)
SWIGINTERN PyObject *_wrap_CastToDerived(PyObject *SWIGUNUSEDPARM(self), PyObject *args) {
PyObject *resultobj = 0;
Base *arg1 = (Base *) 0 ;
void *argp1 = 0 ;
int res1 = 0 ;
PyObject * obj0 = 0 ;
Derived *result = 0 ;
if (!PyArg_ParseTuple(args,(char *)"O:CastToDerived",&obj0)) SWIG_fail;
res1 = SWIG_ConvertPtr(obj0, &argp1,SWIGTYPE_p_Base, 0 | 0);
if (!SWIG_IsOK(res1)) {
SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "CastToDerived" "', argument " "1"" of type '" "Base *""'");
}
arg1 = reinterpret_cast< Base * >(argp1);
result = (Derived *)CastToDerived(arg1);
resultobj = SWIG_NewPointerObj(SWIG_as_voidptr(result), SWIGTYPE_p_Derived, 0 | 0);
return resultobj;
fail:
return NULL;
}
任何幫助將不勝感激。
- 馬特
什麼是對GetBase生成的代碼()是什麼樣子?該錯誤意味着傳遞給CastToDerived的對象不是正確的類型 - 它是什麼類型? – 2010-10-13 12:28:35
爲什麼它的價值,我只是試圖創建一個基於上述的例子,使用swig 1.3.40,我沒有得到這個錯誤。 – 2010-10-13 12:45:20
很奇怪......我試着寫一些類似你的例子的東西,克里斯,而且確實有效。正如你所預料的那樣,我實際遇到的代碼並不是玩具問題,我只是玩弄它,以使它足夠短以適應一個問題。我當前的解決方法是在我的C++庫中定義CastToDerived函數,而不是在.i文件中的%inline%{...%}塊中。這解決了這個問題。也許這個細節可能是對正確人物的暗示?我仍然希望我可以不用將SWIG助手添加到我的C++庫中。 – SuperElectric 2010-10-13 22:33:08