2015-01-15 14 views
7

Tôi có ví dụ trình bao bọc C++ đính kèm cho python: Hàm thành viên (phương thức) là tĩnh với đối số mặc định. Vì vậy, tôi sử dụng BOOST_PYTHON_MEMBER_FUNCTION_OVERLOADS để xác định hàm quá tải. Không có lỗi biên dịch, tuy nhiên khi tôi gọi hàm thành viên tĩnh tôi nhận được lỗi như sau:Boost Python bọc quá tải hàm thành viên tĩnh với đối số mặc định

import boostPythonTest  
boostPythonTest.C.method("string") 
--------------------------------------------------------------------------- ArgumentError Traceback (most recent call last) 
<ipython-input-4-ab141804179c> in <module>() 
----> 1 boostPythonTest.C.method("string") 

ArgumentError: Python argument types in 
C.method(str) did not match C++ signature: 

method(class C {lvalue}, class std::basic_string<char,struct 
std::char_traits<char>,class std::allocator<char> >) 

method(class C {lvalue}, class std::basic_string<char,struct 
std::char_traits<char>,class std::allocator<char> >, int) 

method(class C {lvalue}, class std::basic_string<char,struct 
std::char_traits<char>,class std::allocator<char> >, int, bool) 

Tôi không hiểu tại sao chữ ký được tạo ra đầu tiên là "class C { lvalue} ". Nếu như vậy hàm thành viên tĩnh cần một cá thể của C được gọi, có vẻ mâu thuẫn với tôi.

Mặt khác, tôi xác định một hàm thành viên tĩnh khác mà không sử dụng quá tải hàm thành viên, nó hoạt động mà không có chữ ký "class C {lvalue}". Ví dụ:

boostPythonTest.C.noDefaultArgMethod("string", 0, True) 

Loại: chức năng Form String: docstring: noDefaultArgMethod ((str) arg1, (int) arg2, (bool) arg3) -> int:

C++ signature : 
    int noDefaultArgMethod(

lớp std :: basic_string, lớp std :: cấp phát>, int, bool)

bất cứ ai có thể giúp giải thích các vấn đề với BOOST_PYTHON_MEMBER_FUNCTION_OVERLOADS, hoặc cung cấp cho quá tôi đề nghị làm thế nào để sử dụng nó như là chức năng thành viên tĩnh thực sự với quá tải?

#include <boost/python/module.hpp> 
#include <boost/python/def.hpp> 
#include <boost/python/args.hpp> 
#include <boost/python/tuple.hpp> 
#include <boost/python/class.hpp> 
#include <boost/python/overloads.hpp> 
#include <boost/python/return_internal_reference.hpp> 
#include <boost/python/register_ptr_to_python.hpp> 
#include <boost/python/object/class.hpp> 

using namespace boost::python; 

class C { 
public: 
    static int method(const std::string &arg1, int arg2 = 0, bool arg3 = true) { 
     return 1; 
    }; 

    static int noDefaultArgMethod(const std::string &arg1, int arg2 = 0, bool arg3 = true) { 
     return 10; 
    }; 

}; 

BOOST_PYTHON_MEMBER_FUNCTION_OVERLOADS(method1, C::method, 1, 3) 

BOOST_PYTHON_MODULE(boostPythonTest) 
{ 

    class_<C>("C") 
     .def("method", (int(C::*)(const std::string&, int, bool))0, method1()) 
     .staticmethod("method") 
     .def("noDefaultArgMethod", &C::noDefaultArgMethod) 
     .staticmethod("noDefaultArgMethod"); 

} 

Trả lời

4

tôi tin rằng dòng này:

.def("method", (int(C::*)(const std::string&, int, bool))0, method1()) 

sẽ trông như thế này:

.def("method", &C::method, method1()) 

Và bạn nên sử dụng BOOST_PYTHON_FUNCTION_OVERLOADS thay vì BOOST_PYTHON_MEMBER_FUNCTION_OVERLOADS, vì không có C đối tượng liên quan (chức năng tĩnh con trỏ chỉ là con trỏ hàm, chúng không phải là con trỏ tới thành viên).

Ngoài ra còn có một ví dụ được đăng trên this wiki với chức năng tĩnh quá tải, nơi mà các phần có liên quan sẽ là:

class X { 
    static int returnsum(int m, int x = 10) { return m + x; } 
}; 

BOOST_PYTHON_FUNCTION_OVERLOADS(X_returnsum_overloads, X::returnsum, 1, 2) 

BOOST_PYTHON_MODULE(foo) 
{ 
    class_<X>("X", ..) 
     .def("returnsum", &X::returnsum, 
      X_returnsum_overloads(args("x", "m"), "returnsum's docstring") 
      ) 
     .staticmethod("returnsum") 
     ; 
} 

Đó có vẻ như chính xác những gì bạn muốn.

+0

Điều đó thật tuyệt. Cảm ơn nhiều. – David

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