2013-06-21 36 views
1

我通過添加一個私有成員變量,並且在bar()功能打印它延伸在這個answer提供的示例:用ctypes包裝簡單的C++示例;分段錯誤

#include <iostream> 
class Foo{ 
    private: 
     double m; 
    public: 
     Foo() { m = 2.344; }; 
     void bar(){ 
      std::cout << "Hello, number is " << m << std::endl; 
     } 
}; 

extern "C" { 
    Foo* Foo_new(){ return new Foo(); } 
    void Foo_bar(Foo* foo){ foo->bar(); } 
} 

的​​包裝是不變,並且是:

from ctypes import * 
lib = cdll.LoadLibrary('./libfoo.so') 

class Foo(object): 
    def __init__(self): 
     self.obj = lib.Foo_new() 

    def bar(self): 
     lib.Foo_bar(self.obj) 



f = Foo() 
f.bar() 

當我運行Python代碼(之前已經編譯了C++代碼),我得到了一個分段錯誤,我已經縮小到bar()中的m的打印。

賽格故障不會在原來的代碼

  • 發生

    1. 如果我刪除的m打印,但把它作爲一個變量
    2. 如果我bar()與任何固定數量的替代m

    我真的很困惑爲什麼會出現這種情況。由於這是一個學習ctypes的實驗,任何幫助將不勝感激。

  • +0

    問題並不在於'm'變量,而是當C++代碼試圖引用與'this'有關的任何東西時。我假設,由於某種原因,它沒有正確設置。你可以在你的C++代碼中添加一些調試語句,以便在調用Foo :: bar()時跟蹤創建的對象的地址和this的值嗎? –

    +0

    嘗試在C++類中進行非內聯 – Krab

    +0

    我只是嘗試了完全相同的代碼(g ++ 4.4.5,Python 2.6.6),它像一個魅力一樣工作。 –

    回答

    3

    如果您使用的是64位Python,則需要定義restypeargtypes。否則ctypes默認將這些值轉換爲32位C int

    from ctypes import * 
    
    lib = CDLL('./libfoo.so') 
    
    lib.Foo_new.argtypes = [] 
    lib.Foo_new.restype = c_void_p 
    
    lib.Foo_bar.argtypes = [c_void_p] 
    lib.Foo_bar.restype = None 
    

    下面是2.7.5,模塊/ _ctypes/callproc.c源鏈接:

    對於64位的Windows一個C long是32位,但在大多數其他64位平臺上是64位。通過強制int,結果至少是一致的。