2014-04-18 40 views
3

我正在使用SWIG來包裝2個C++對象,並且我在我的應用程序中嵌入了Python解釋器(即調用PyInitialize()等)。使用SWIG將C++對象指針傳遞給Python,而不是返回到C++

第一個對象是一些應用程序數據的包裝。 第二個是「幫助器」對象,也是用C++編寫的,它可以根據它在數據對象中找到的內容執行某些操作。

python腳本決定何時/如何/是否調用助手對象。

所以我一個指針傳遞給我的C++對象痛飲/ Python的這樣:

swig_type_info *ty = SWIG_MangledTypeQuery("_p_MyDataObject"); 
if(ty == NULL) 
{ 
    Py_Finalize(); 
    return false; 
} 

PyObject *data_obj = SWIG_NewPointerObj(PointerToMyDataObject, ty, 0); 
if(data_obj == NULL) 
{ 
    Py_Finalize(); 
    return false; 
} 

ty = SWIG_MangledTypeQuery("_p_MyHelperObject"); 
if(ty == NULL) 
{ 
    Py_Finalize(); 
    return false; 
} 

PyObject *helper_obj = SWIG_NewPointerObj(PointerToMyHelperObject, ty, 0); 
if(helper_obj == NULL) 
{ 
    Py_Finalize(); 
    return false; 
} 
PyTuple_SetItem(pArgs, 0, data_obj); 
PyTuple_SetItem(pArgs, 1, helper_obj); 
PyObject *pValue = PyObject_CallObject(pFunc, pArgs); 
if(pValue == NULL) 
{ 
    Py_Finalize(); 
    return false; 
} 

在Python中,我們看到的是這樣的:

def go(dataobj, helperobj): 
    ## if conditions are right.... 
    helperobj.helpme(dataobj) 

現在,這主要是工作,除了一件事。在我準備傳遞給Python腳本的參數時,在我的C++代碼中,觀察PointerToMyDataObject的指針值。

當我在helperobj.helpme()的C++實現中設置斷點時,我發現內存地址不同,儘管它似乎是指向MyDataObject的有效實例的指針。

這對我很重要,因爲「MyDataObject」實際上是一些可能派生類的基類。我的幫助對象想要對接收的指針執行一個適當的(通過上下文確定的)動態強制轉換,以指向適當的派生類。這是我認爲現在顯而易見的原因的失敗。

我讀過有關在痛飲「影子」的對象,這隻會增加我的困惑(道歉我的小大腦:-P)

所以,在夜風使我對象的副本對於一些有些事原因,然後傳遞一個指向副本的指針?如果是這樣,那麼我可以理解爲什麼我對動態演員的假設不起作用。

我試圖添加這個作爲評論,但與格式的努力,所以.....更多見解如下: 該問題與傳遞引用。通知我)的虛擬方法helpMe(2個實施方式:

bool MyHelperObject::helpMe(MyDataObject mydata_obj) 
{ 
    return common_code(&mydata_obj); 
} 
bool MyHelperObject::helpMe(MyDataObject *mydata_obj) 
{ 
    return common_code(mydata_obj); 
} 

雖然我用指針提供蟒,它被調用傳遞通過引用版本。這解釋了爲什麼我得到不同的指針值。但是我能做些什麼來強制對需要指針參數的版本進行調用?

+0

你能重新關注這個問題一點,顯示更清晰什麼你想包裝的C++接口(具有完整的,但最小的實現)看起來像?我對自己的想法有了一個想法,但我寧願不花時間回答,直到我知道我們都在同一頁面上。 – Flexo

回答

1

根據您所示,我認爲您要確保SWIG只能看到指針版本helpMe。非指針版本將創建一個臨時副本,然後將其傳遞給該函數,聽起來像這不是你想要的。

SWIG將很難挑選使用哪個版本,因爲它會略微提取指針概念以更好地匹配Python。

,您可以隱藏SWIG非指針版本%ignore聲明之前或%import,顯示它在你的接口文件痛飲:

%ignore MyHelperObject::helpMe(MyDataObject mydata_obj) 
%import "some.h" 
相關問題