2012-02-29 60 views
2

最近我一直在包裝的python很多C++代碼,我覺得這是塊(直接從python documentation拍攝)有些令人擔憂:鑄造PyCFunctionWithKeywords

static PyMethodDef keywdarg_methods[] = { 
/* The cast of the function is necessary since PyCFunction values 
* only take two PyObject* parameters, and keywdarg_parrot() takes 
* three. 
*/ 
{"parrot", (PyCFunction)keywdarg_parrot, METH_VARARGS | METH_KEYWORDS, 
"Print a lovely skit to standard output."}, 
{NULL, NULL, 0, NULL} /* sentinel */ 
}; 

的問題是線,將kwarg_parrot類型PyCFunctionWithKeywords轉換爲PyCFunction

從C++背景的(並考慮到我包裹C++代碼),它似乎是錯誤使用C樣式轉換。我試過static_castdynamic_cast,這兩者都會導致編譯器抱怨(有很好的理由,這在一般意義上確實是不安全的)。唯一可行的C++選項似乎是reinterpret_cast,但據我所知,這是C風格演員的更詳細版本。

當然,上面的包裝在extern "C"塊中,所以也許C方式是正確的方法。有沒有人有更好的想法? (我很想看看會是可以自動生成基於關鍵詞的文檔字符串的解決方案。)

不幸的是,像Boost.Python的和呷解決方案是假表。 (我是一個醜陋的框架內工作)

+0

C++中的「C cast」被稱爲reinterpret_cast,可以隨意使用它。 – 2012-02-29 10:10:37

+0

我不認爲有一種方法可以避免演員(C風格或重新解釋),因爲Python包裝是按照這種方式設計的。你應該傳遞各種函數指針,但你必須讓它們看起來像一個PyCFunction。深入下來,它們將根據您設置的選項(如「METH_VARARGS」)重新解釋。 – jogojapan 2012-02-29 10:20:58

+0

您究竟想要如何構建文檔字符串?我完全不理解。 – jogojapan 2012-02-29 10:21:30

回答

1

主要Python的實現是用C寫的,而不是C++。

因此,評估keywdarg_methods[]的libpython代碼是用C編寫的,並且通過C調用約定調用keywdarg_parrot

如果你想C++和Python風格的融合,找到一種方法,而不是使用Boost.Python的。或者也許是cython。

+2

不,我也像Shep一樣包裝了很多C++。這是有效的,但實際上類型轉換是醜陋的。 – jogojapan 2012-02-29 10:17:32

+0

Boost.Python的主要問題是讓它能夠與許多不同版本的python和許多不同的計算集羣一起工作。我們經常編寫發送到集羣的代碼,並在那裏構建,然後使用可能缺少相應的Boost.Python版本的python版本運行。將構建系統指向Python頭文件通常很困難,更別說構建boost庫了。 – Shep 2012-02-29 11:23:07

+0

也許你的自定義C包裝是完全正確的。 – 2012-03-01 13:02:28

1

PyMethodDef是Python C API,所以我只想用一個C鑄件的一部分。它的工作原理就是所有Python extenaions都在使用的。保持一致。

使用C++與不是Python API中的一部分對象時施放。