2012-03-08 33 views
11

Tôi đang triển khai mô-đun mở rộng Python bằng cách sử dụng Boost.Python. Mô-đun sẽ xác định các lớp ngoại lệ tùy chỉnh của riêng nó kế thừa Exception. Làm thế nào để làm điều đó?Boost.Python lớp ngoại lệ tùy chỉnh

+1

Làm cho lỗi của bạn được kế thừa từ 'Ngoại lệ'; 'StandardError' được sử dụng bởi các lỗi được tạo ra bởi các công cụ từ thư viện chuẩn python. – Daenyth

+0

@Denyeny: Bạn nói đúng. Tôi đã sửa đổi câu hỏi. – user763305

Trả lời

12

Hàm sau tạo một lớp ngoại lệ Python mới và thêm nó vào phạm vi hiện tại. Nếu nó được gọi trong hàm khởi tạo mô-đun, thì nó sẽ được thêm vào mô-đun.

Đối số đầu tiên là tên của lớp ngoại lệ mới. Đối số thứ hai là đối tượng kiểu cho lớp cơ sở của lớp ngoại lệ mới; nó mặc định là đối tượng kiểu cho Exception. Giá trị trả về là đối tượng kiểu cho lớp ngoại lệ mới.

PyObject* createExceptionClass(const char* name, PyObject* baseTypeObj = PyExc_Exception) 
{ 
    using std::string; 
    namespace bp = boost::python; 

    string scopeName = bp::extract<string>(bp::scope().attr("__name__")); 
    string qualifiedName0 = scopeName + "." + name; 
    char* qualifiedName1 = const_cast<char*>(qualifiedName0.c_str()); 

    PyObject* typeObj = PyErr_NewException(qualifiedName1, baseTypeObj, 0); 
    if(!typeObj) bp::throw_error_already_set(); 
    bp::scope().attr(name) = bp::handle<>(bp::borrowed(typeObj)); 
    return typeObj; 
} 

Sử dụng các chức năng như sau:

Gọi hàm trong các chức năng mô-đun khởi tạo và lưu trữ các giá trị trả về trong một biến toàn cầu:

PyObject* myExceptionTypeObj = 0; 

BOOST_PYTHON_MODULE(MyModule) 
{ 
    ... 
    myExceptionTypeObj = createExceptionClass("MyException"); 
    ... 
} 

Raise ngoại trừ loại MyModule.MyException:

PyErr_SetString(myExceptionTypeObj, "Oh my!") 
+4

Nói 'MyException' thực sự ánh xạ thành kiểu C++. Làm cách nào để tôi phơi bày các thành viên của mình? – Barry

-1

@Kenny:

Nếu bạn tham khảo

PyErr_SetString(myExceptionTypeObj, "Oh my!") 

tôi sẽ không coi đây là "sao chép chuỗi đến một đối tượng toàn cầu". Thay vào đó, nó đặt chỉ báo lỗi nội bộ của Python để trình thông dịch sẽ tăng một cá thể của myExceptionTypeObj vào lần kiểm tra chỉ báo lỗi tiếp theo của nó.

Xử lý ngoại lệ của Python hoạt động với chỉ báo lỗi toàn cầu (theo chuỗi Python) và đây là cách thông thường để tăng ngoại lệ thông qua việc loại bỏ API C.

Việc tôi thực hiện nó là bạn an toàn nếu bạn giữ GIL tại thời điểm này và sẽ gây ra một ngoại lệ trong chuỗi Python mà mã C của bạn được nhập từ đó.

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