2017-08-31 83 views
2

我想要包裝一些使用結構函數的結構函數的C++代碼,而不是搞清楚如何。直接從cython調用C++結構構造函數

C++結構:

typedef struct point_3d_t 
{ 
    double x; 
    double y; 
    double z; 

    point_3d_t(double x, double y, double z) 
     : x(x) 
     , y(y) 
     , z(z) 
     {} 

} point_3d; 

用Cython包裝:

cdef extern from "./cppdar.hpp": 
    ctypedef struct point_3d: 
     point_3d(double, double, double) 
     double x; 
     double y; 
     double z; 

現在,我希望能夠通過的東西來構建結構類似cdef point_3d p1(v, v, v)(從用Cython文件中) ,但我似乎無法弄清楚如何讓cython只使用提供的構造函數。

我已經試過:

  • cdef point_3d p1(v, v, v)
  • cdef point_3d p1 = point_3d(v, v, v)
  • cdef point_3d p1(0, 0, 0)
  • cdef point_3d p1 = point_3d(0, 0, 0)

v是一個明確的cdef double v = 0,但沒有工作。

使用普通cdef point_3d p1,p1.x = nnnn等,但這很煩人,我不明白爲什麼我不應該能夠使用默認的構造函數,我認爲。

試圖研究這個問題產生了很多與類構造函數有關的混亂,這沒有幫助。

回答

1

好了,答案是你不能構造函數的參數在用Cython在所有堆棧分配C++對象,基本上

來源:https://groups.google.com/forum/#!topic/cython-users/fuKd-nQLpBs

是的,這是一個限制,但這是一個比解析器更基本的問題。堆棧分配的對象的在 C++的構造和破壞密切關聯的其範圍,並且範圍規則 在Python和C不同。例如,考慮

if some_condition(): 
    x = Foo(1) 
else: 
    x = Foo(2, 3) 
return x.method() 

這根本不能被表示爲這樣的在C++中。相反地​​

if (some_other_condition()) { 
    Foo_with_RIAA foo(x) 
} 
... 

不會正確地翻譯Python範圍規則。

現在也有一些情況下,它可能是有意義的,但顯著 代碼生成變化將必須作出,因爲目前所有 變量都在函數的頂部(遵循C89 標準,其中一些聲明編譯器強制執行),但在C++模式下,我們將有 將變量的聲明推遲到它的實例化 (包括避免爲了代碼生成的簡單性而使用任何自動插入的C級作用域 )。

因爲人們總是可以在堆上分配這樣複雜的對象,所以這個 不是一個重要的限制。

這是額外的雙加煩,因爲這意味着你根本不能缺乏在許多情況下,默認的構造函數包裝類。


的可怕,沒有良好的哈克解決方法是包裹在一個簡單的C(++)函數的構造函數,然後通過用Cython暴露

+0

我不確定我明白你的工作環境能讓你滿意嗎?你仍然需要一個默認的構造函數才能使用。 – DavidW

+0

@DavidW - 是的,你仍然會得到一個構造,構建和移動過程,但實例化爲默認值然後單獨設置成員會更好。 –

+0

我相信Cython可以做構建然後複製賦值/移動賦值:'cdef point_3d p'然後'p = point_3d(...)'。您可能需要告訴它有關默認構造函數以及您使用的構造函數。 – DavidW