2010-12-02 24 views
18

C++ 'dan çağrı Python işlevlerini gerçekleştirmeye çalışıyorum. Fonksiyon göstergeleri ile elde edilebileceğini düşündüm, ama mümkün görünmüyor. Bunu yapmak için boost.python kullanıyordum.Python işlevlerini çağırma C++

def callback(arg1, arg2): 
    #do something 
    return something 

Şimdi oradan çağrılabilir, böylece C++ için bu fonksiyonu geçmesi gerekiyor:

Python tanımlanan bir işlev olmadığını varsayalım. Bunu elde etmek için kodu boost.python kullanarak C++ tarafında nasıl yazarım?

cevap

15

herhangi yazabileceği: a boost::python::object götüren işlevine

Geçiş bunu.

bp::object pycb; //global variable. could also store it in a map, etc 
void register_callback(bp::object cb) 
{ 
     pycb = cb; 
} 

tutarlı bir adla tek bilinen ad alanında ise: Hemen gidip PyRun_SimpleString("myFunction()") kullanılan

ret = pycb() 
+0

Thnks Matthew, Başka bir sorum var. Burada aynı konudan python nesnesi çağrılıyor. Ya python nesnesi globalyse ve farklı bir iş parçacığı deniliyorsa? – Amar

+0

Bu sorunun kapsamı biraz da olsa mümkün olabilir. C/Python API'sının PyGILState_ * işlev ailesini araştırmanızı tavsiye ederim. Boost-Python'un aksine, Python'un çok iyi dokümanları var. Daha fazla yardıma ihtiyacınız varsa, başka bir soru sorun. –

+2

Gelecekte görüntüleyenler için: Birisi sonunda başka bir soru sordu ve cevapladım. Buraya bakın: stackoverflow.com/questions/8009613/boost-python-not-supporting-parallelism/8011153#8011153 –

4

Bir ipucu değil. Ancak, işlev nesnesine sahip olduğunuzda onu çağırmak için PyObject_Call()'u kullanabilirsiniz.

+2

Eğer bir "boyt :: python :: object" dosyanız varsa, onu çağırmak için 'operator()' işlevini kullanabilirsiniz. – eudoxos

2

Daha önce kullanmadım, ancak başvuru kılavuzunda, bunun nasıl yapılacağını gösteren Calling Python Functions and Methods adlı bir bölümü vardır.

+1

Yükseltme python belgeleri güncel olmadığında bile büyük ölçüde güncel değildir ve son derece kötüdür. –

+0

Ah Denedim. :-) – Ken

+0

Bu sayfa size bir Python işlevi göstermiyor. Sadece önceden bağlı bir nesneyi nasıl arayacağınızı gösterir. Tam olarak "basit bir örnek" değil. – CashCow

1

herhangi işlev gibi diyoruz böylece

bp::object

bp::object pycb = bp::scope("namespace").attr("callback"); 
operator(), tanımlamıştır fonksiyonumun adı bilindiği için çabuk bir hack olarak, __main__ ad alanı içinde herhangi bir hata alıp yaşamadı. Birden çok iş parçacığınız varsa ek olarak GIL kilidi almanız gerektiğini unutmayın.

İlgili konular