Vấn đề: Tôi đã gói một số mã C++ trong python bằng SWIG. Về phía trăn, tôi muốn lấy một con trỏ C++ được bọc và đặt nó xuống thành một con trỏ tới một lớp con. Tôi đã thêm một hàm C++ mới vào tệp SWIG .i thực hiện thao tác này, nhưng khi tôi gọi nó từ python, tôi nhận được một TypeError.Làm cách nào để bỏ qua đối tượng C++ từ trình bao bọc SWIG trăn?
Dưới đây là các chi tiết:
Tôi có hai lớp C++, Cơ sở và Nguồn gốc. Có nguồn gốc là một phân lớp của Base. Tôi có một lớp thứ ba, Container, chứa một Derived, và cung cấp một accessor cho nó. Accessor trả về Derived dưới dạng const Base &, như được hiển thị:
class Container {
public:
const Base& GetBase() const {
return derived_;
}
private:
Derived derived_;
};
Tôi đã bọc các lớp này vào python bằng SWIG. Trong mã python của tôi, tôi muốn down tham chiếu Base trở lại một Derived. Để làm điều này, tôi đã viết vào uống một lân .i nộp một hàm helper trong C++ mà không xuống-đúc:
%inline %{
Derived* CastToDerived(Base* base) {
return static_cast<Derived*>(base);
}
%}
Trong mã python của tôi, tôi gọi chức năng này xuống đúc:
base = container.GetBase()
derived = CastToDerived(base)
Khi tôi làm như vậy, tôi nhận được lỗi sau:
TypeError: in method 'CastToDerived', argument 1 of type 'Base *'
Tại sao có thể này xảy ra?
Để tham khảo, dưới đây là các bit liên quan của tệp .cxx được tạo bởi SWIG; cụ thể là chức năng gốc và giao diện python-ified doppelganger của nó:
Derived* CastToDerived(Base* base) {
return static_cast<Derived*>(base);
}
// (lots of other generated code omitted)
SWIGINTERN PyObject *_wrap_CastToDerived(PyObject *SWIGUNUSEDPARM(self), PyObject *args) {
PyObject *resultobj = 0;
Base *arg1 = (Base *) 0 ;
void *argp1 = 0 ;
int res1 = 0 ;
PyObject * obj0 = 0 ;
Derived *result = 0 ;
if (!PyArg_ParseTuple(args,(char *)"O:CastToDerived",&obj0)) SWIG_fail;
res1 = SWIG_ConvertPtr(obj0, &argp1,SWIGTYPE_p_Base, 0 | 0);
if (!SWIG_IsOK(res1)) {
SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "CastToDerived" "', argument " "1"" of type '" "Base *""'");
}
arg1 = reinterpret_cast< Base * >(argp1);
result = (Derived *)CastToDerived(arg1);
resultobj = SWIG_NewPointerObj(SWIG_as_voidptr(result), SWIGTYPE_p_Derived, 0 | 0);
return resultobj;
fail:
return NULL;
}
Bất kỳ trợ giúp nào cũng sẽ được đánh giá cao.
- Matt
gì mã được tạo cho GetBase() như thế nào? Lỗi có nghĩa là đối tượng được truyền vào CastToDerived là loại không đúng - loại đó là gì? –
Đối với những gì nó có giá trị, tôi chỉ cố gắng tạo ra một ví dụ dựa trên ở trên, sử dụng swig 1.3.40, và tôi đã không nhận được lỗi này. –
Lạ thật ... Tôi đã thử viết một cái gì đó giống như ví dụ của bạn, Chris, và thực sự nó đã hoạt động. Như bạn có thể mong đợi, mã tôi thực sự gặp rắc rối với không phải là một số vấn đề đồ chơi, tôi chỉ đồ chơi-ified nó để làm cho nó đủ ngắn để phù hợp trong một câu hỏi. Cách khắc phục hiện tại của tôi là xác định hàm CastToDerived trong thư viện C++ của tôi, thay vì trong khối% inline% {...%} trong tệp .i. Điều đó khắc phục được sự cố. Có lẽ chi tiết đó có thể là một gợi ý cho đúng người? Tôi vẫn muốn tôi có thể làm mà không cần thêm SWIG helpers vào thư viện C++ của tôi. – SuperElectric