2010-05-31 26 views
5

Tôi cần viết mã để thực hiện một số xử lý thời gian thực khá phức tạp về mặt tính toán. Tôi muốn tạo một số lớp Python để quản lý tất cả các kịch bản của tôi, và để lại các phần chuyên sâu của thuật toán được mã hóa trong C++ để chúng có thể chạy nhanh nhất có thể. Tôi muốn khởi tạo các đối tượng trong Python, và có các thuật toán C++ trở lại kịch bản với callbacks trong python. Một cái gì đó như:Xử lý thời gian thực và gọi lại bằng Python và C++

myObject = MyObject() 
myObject.setCallback(myCallback) 
myObject.run() 

def myCallback(val): 
    """Do something with the value passed back to the python script.""" 
    pass 

Điều này có thể thực hiện được không? Làm thế nào tôi có thể chạy một cuộc gọi lại trong python từ một vòng lặp đang chạy trong một mô-đun C + +? Bất cứ ai có một liên kết hoặc một hướng dẫn để giúp tôi làm điều này một cách chính xác?

Trả lời

3

Tôi khuyên bạn nên sử dụng Boost.Python như đề xuất của ChristopheD. Một gotcha sẽ là nếu phần mở rộng C++ đang chạy trong bối cảnh chủ đề riêng của nó (không được tạo bởi Python). Nếu đúng như vậy, hãy đảm bảo sử dụng các hàm PyGILState_Ensure() and PyGILState_Release() khi gọi vào mã Python từ C++.

Từ các tài liệu (http://docs.python.org/c-api/init.html#thread-state-and-the-global-interpreter-lock):

Bắt đầu với phiên bản 2.3, đề bây giờ có thể tận dụng lợi thế của PyGILState _ *() chức năng để làm tất cả trên tự động. Các điển hình thành ngữ để gọi vào Python từ một sợi C bây giờ là:

PyGILState_STATE gstate; 
gstate = PyGILState_Ensure(); 

/* Perform Python actions here. */ 
result = CallSomeFunction(); 
/* evaluate result */ 

/* Release the thread. No Python API allowed beyond this point. */ 
PyGILState_Release(gstate) 

Tôi khuyên bạn nên làm cho callbacks ngắn & ngọt - để hạn chế sự cần thiết phải thực hiện xử lý ngoại lệ trong C++. Nếu bạn đang sử dụng wxPython, bạn có thể sử dụng hệ thống sự kiện async mạnh mẽ. Hoặc các callbacks có thể đặt các sự kiện trên một Queue và bạn có thể có một luồng dành cho việc thực hiện không đồng bộ mã gọi lại/sự kiện.

Ngay cả với phép thuật Boost.Python, bạn sẽ phải làm quen với phần này của API Python C khi xử lý các chuỗi. (Đừng quên bọc các hàm C++ với Py_BEGIN_ALLOW_THREADSPy_END_ALLOW_THREADS để giải phóng GIL!)

0

Here là ví dụ về cách thực hiện lệnh gọi lại python bằng cách sử dụng Cython. Nó có thể là giá trị nhìn vào Pyrex là tốt. Cả hai đều có thể tích hợp C/C++ với Python khá dễ dàng.

0

Chúng tôi làm những gì bạn đang làm rất nhiều trong công việc. Chúng tôi thích python nhưng đôi khi nó không đủ nhanh.
BoostSwig đều tốt cho việc đó. Bạn cũng nên kiểm tra liên kết này trên Python Performance họ nói một chút về NumPy có thể giúp bạn.

Các vấn đề liên quan