簡體   English   中英

使用SWIG作為具有輸入參數功能的函數

[英]Using SWIG for functions with functions as input parameter

考慮以下最小的例子:我有一個C ++函數'myfun',它接受一個數字和另一個函數作為輸入,並返回在x處計算的函數:

雙myfun(雙x,雙(* f)(雙y))
{return f(x); }

我將此代碼存儲在'test.cpp'中。 相應頭文件'test.hpp'中的代碼很簡單

double myfun(double x,double(* f)(double y));

現在,我嘗試使用SWIG從Python訪問'myfun'。 'swig.i'文件如下所示:

%模塊測試
%{
#include“test.hpp”
%}
double myfun(double x,double(* f)(double y));

每當我嘗試在Python中調用此函數時,例如使用

從測試導入myfun
myfun(2,lambda y:y ** 2)

我收到錯誤:

在方法'myfun'中,參數2'double(*)(double)'

所以我的問題很簡單:如何修改'swig.i'文件,以便我可以將任何(合適的Python)函數傳遞給'myfun'? (這個問題與這篇文章有點相關如何包裝一個c ++函數,它使用SWIG接收python中的函數指針 '但不同之處在於我在C ++中沒有指定輸入函數,而是我想保持它為一個免費的“參數”)。

在編寫綁定時回調需要額外的處理,這在SWIG中尚未得到支持,顯然沒有真正的解決方法。

重點是SWIG是關於從Python(和其他語言)調用C,而不是從C調用Python。

我們使用的是SIP ,它是一個更復雜的綁定生成器(不過是C ++ / Python特有的)。 SIP支持回調甚至從C ++類繼承Python類。

該工具非常強大,是PyQt綁定的引擎。

但請注意,Python中的可調用函數不僅僅是C ++中的函數,因為它可以包含上下文(它可以是閉包)。 在C ++代碼中:

int callF(int (*f)(int, int), int a, int b) {
    return f(a, b);
}

只能調用一個純無上下文的函數,所以傳遞一般的Python回調是不可能的,因為沒有足夠的信息(唯一的解決方案是分配預編譯的trampolines或在運行時生成C ++代碼)。

如果你可以控制雙方,但是解決方法是創建一個包含回調的C類並在Python中派生它。 例如:

struct CBack {
    virtual int operator()(int x, int y) const {
        return x+y;
    }
    virtual ~CBack() {}
};

int callF(const CBack& f,
          int xv, int yv)
{
    return f(xv, yv);
}

然后從CBack派生一個Python類並傳遞:

class Add(CBack):
    def __call__(self, x, y):
        return x + y

class Mul(CBack):
    def __call__(self, x, y):
        return x * y

print callF(Add(), 3, 7) # will print 10
print callF(Mul(), 3, 7) # will print 21

在這種情況下,你也可以傳遞一個(包裹的)lambda

def cback(f):
    class PyCBack(CBack):
        def __call__(self, x, y):
            return f(x, y)
    return PyCBack()

print callF(cback(lambda x, y: x*y), 3, 7)

換句話說,一個阻抗問題是C ++的函數與Python的函數不同(Python的函數也可以有上下文)。

可以從這里下載完整的示例。

根據文件 (強調我的):

盡管SWIG通常不允許以目標語言編寫回調函數 ,但這可以通過使用類型映射和其他高級SWIG功能來實現。

如果您想深入了解該主題, 是建議的章節。
無論如何,它看起來不是該工具的預期關鍵功能。
您可以做的最好的事情是獲得一個圍繞Python設計的解決方案,並且不能與其他目標語言一起使用,但它通常不是Swig的用戶想要的。

請注意,您仍然可以在C / C ++中編寫回調並將它們作為常量導出,然后從目標語言中使用它們。
有關詳細信息,請參閱上面的文檔。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM