Tôi đang gặp sự cố khi sử dụng các hàm từ thư viện được chia sẻ được xuất với giao diện SWIG .dll
.Sử dụng các chức năng bọc SWIG từ Windows .dll
Version Info
Python: 2.6.4
Swig: 2.0.4
Bức tranh lớn là: Tôi có một số mã được phát triển trong Linux bằng C++ và được bọc bằng SWIG. Tôi đã biên dịch nguồn C++ thành đối tượng .so
trong Linux và sử dụng thư viện .so
bằng Python.
Bây giờ, tôi cần di chuyển tất cả các chức năng này sang cửa sổ và tương đương với .so
trong Windows là .dll
. Vì vậy, tôi đã lên kế hoạch biên dịch tất cả các mã nguồn C++ thành một .dll
và truy cập chúng thông qua Python.
Vì vậy, thủ tục bình thường sẽ là: có nguồn C++ -> bọc chúng bằng SWIG -> biên dịch thành .dll
-> truy cập thông qua Python.
Có một tệp nguồn lớn .cxx
được tạo bằng SWIG chứa tất cả các chức năng tôi đã phát triển. Nhiệm vụ bây giờ là biên dịch tập tin được tạo ra SWIG này thành một .dll
để tôi có thể sử dụng tất cả các chức năng sau này. Tuy nhiên, tệp .cxx sử dụng một số cách kỳ lạ để gói tất cả các chức năng của tôi và tôi không có đầu mối làm thế nào để sử dụng chúng.
Các chức năng được bao bọc như sau. Ssay Tôi có một ++ lớp C gọi sdrts_reverse_burst_ff
, sau khi gói, lớp trở thành một chức năng trong file .cxx
và được định nghĩa như thế này:
SWIGINTERN PyObject *_wrap_sdrts_reverse_burst_ff_sptr___deref__(PyObject *SWIGUNUSEDPARM(self), PyObject *args) {
PyObject *resultobj = 0;
boost::shared_ptr<sdrts_reverse_burst_ff> *arg1 = (boost::shared_ptr<sdrts_reverse_burst_ff> *) 0 ;
void *argp1 = 0 ;
int res1 = 0 ;
PyObject * obj0 = 0 ;
sdrts_reverse_burst_ff *result = 0 ;
if(!PyArg_UnpackTuple(args,(char *)"sdrts_reverse_burst_ff_sptr___deref__",1,1,&obj0)) SWIG_fail;
res1 = SWIG_ConvertPtr(obj0, &argp1,SWIGTYPE_p_boost__shared_ptrT_sdrts_reverse_burst_ff_t, 0 | 0);
if (!SWIG_IsOK(res1)) {
SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "sdrts_reverse_burst_ff_sptr___deref__" "', argument " "1"" of type '" "boost::shared_ptr<sdrts_reverse_burst_ff> *""'");
}
arg1 = reinterpret_cast< boost::shared_ptr<sdrts_reverse_burst_ff> * >(argp1);
result = (sdrts_reverse_burst_ff *)(arg1)->operator ->();
resultobj = SWIG_NewPointerObj(SWIG_as_voidptr(result), SWIGTYPE_p_sdrts_reverse_burst_ff, 0 | 0);
return resultobj;
fail:
return NULL;
}
Đó không phải là tất cả: gần cuối .cxx
tập tin này có một mảng lớn trong đó có tất cả các chức năng lớp như thế này:
PyMethodDef SwigMethods[] = {
{ (char *)"sdrts_reverse_burst_ff_sptr___deref__", _wrap_sdrts_reverse_burst_ff_sptr___deref__, METH_VARARGS, (char *)"sdrts_reverse_burst_ff_sptr___deref__(sdrts_reverse_burst_ff_sptr self)"},
{ (char *)"delete_sdrts_reverse_burst_ff_sptr", _wrap_delete_sdrts_reverse_burst_ff_sptr, METH_VARARGS, (char *)"delete_sdrts_reverse_burst_ff_sptr(sdrts_reverse_burst_ff_sptr self)"},
{ (char *)"sdrts_reverse_burst_ff_sptr_set_reverse_burst", _wrap_sdrts_reverse_burst_ff_sptr_set_reverse_burst, METH_VARARGS, (char *)"sdrts_reverse_burst_ff_sptr_set_reverse_burst(sdrts_reverse_burst_ff_sptr self, int samples) -> int"},
{ (char *)"sdrts_reverse_burst_ff_sptr_enable_reverse_burst", _wrap_sdrts_reverse_burst_ff_sptr_enable_reverse_burst, METH_VARARGS, (char *)"sdrts_reverse_burst_ff_sptr_enable_reverse_burst(sdrts_reverse_burst_ff_sptr self) -> int"},
{ (char *)"sdrts_reverse_burst_ff_sptr_reset", _wrap_sdrts_reverse_burst_ff_sptr_reset, METH_VARARGS, (char *)"sdrts_reverse_burst_ff_sptr_reset(sdrts_reverse_burst_ff_sptr self) -> int"},
{ (char *)"sdrts_reverse_burst_ff_sptr_history", _wrap_sdrts_reverse_burst_ff_sptr_history, METH_VARARGS, (char *)"sdrts_reverse_burst_ff_sptr_history(sdrts_reverse_burst_ff_sptr self) -> unsigned int"},
{ (char *)"sdrts_reverse_burst_ff_sptr_output_multiple", _wrap_sdrts_reverse_burst_ff_sptr_output_multiple, METH_VARARGS, (char *)"sdrts_reverse_burst_ff_sptr_output_multiple(sdrts_reverse_burst_ff_sptr self) -> int"},
{ (char *)"sdrts_reverse_burst_ff_sptr_relative_rate", _wrap_sdrts_reverse_burst_ff_sptr_relative_rate, METH_VARARGS, (char *)"sdrts_reverse_burst_ff_sptr_relative_rate(sdrts_reverse_burst_ff_sptr self) -> double"},
{ (char *)"sdrts_reverse_burst_ff_sptr_start", _wrap_sdrts_reverse_burst_ff_sptr_start, METH_VARARGS, (char *)"sdrts_reverse_burst_ff_sptr_start(sdrts_reverse_burst_ff_sptr self) -> bool"},
{ (char *)"sdrts_reverse_burst_ff_sptr_stop", _wrap_sdrts_reverse_burst_ff_sptr_stop, METH_VARARGS, (char *)"sdrts_reverse_burst_ff_sptr_stop(sdrts_reverse_burst_ff_sptr self) -> bool"},
{ (char *)"sdrts_reverse_burst_ff_sptr_nitems_read", _wrap_sdrts_reverse_burst_ff_sptr_nitems_read, METH_VARARGS, (char *)"sdrts_reverse_burst_ff_sptr_nitems_read(sdrts_reverse_burst_ff_sptr self, unsigned int which_input) -> uint64_t"},
{ (char *)"sdrts_reverse_burst_ff_sptr_nitems_written", _wrap_sdrts_reverse_burst_ff_sptr_nitems_written, METH_VARARGS, (char *)"sdrts_reverse_burst_ff_sptr_nitems_written(sdrts_reverse_burst_ff_sptr self, unsigned int which_output) -> uint64_t"},
{ (char *)"sdrts_reverse_burst_ff_sptr_detail", _wrap_sdrts_reverse_burst_ff_sptr_detail, METH_VARARGS, (char *)"sdrts_reverse_burst_ff_sptr_detail(sdrts_reverse_burst_ff_sptr self) -> gr_block_detail_sptr"},
{ (char *)"sdrts_reverse_burst_ff_sptr_set_detail", _wrap_sdrts_reverse_burst_ff_sptr_set_detail, METH_VARARGS, (char *)"sdrts_reverse_burst_ff_sptr_set_detail(sdrts_reverse_burst_ff_sptr self, gr_block_detail_sptr detail)"},
{ (char *)"sdrts_reverse_burst_ff_sptr_name", _wrap_sdrts_reverse_burst_ff_sptr_name, METH_VARARGS, (char *)"sdrts_reverse_burst_ff_sptr_name(sdrts_reverse_burst_ff_sptr self) -> string"},
{ (char *)"sdrts_reverse_burst_ff_sptr_input_signature", _wrap_sdrts_reverse_burst_ff_sptr_input_signature, METH_VARARGS, (char *)"sdrts_reverse_burst_ff_sptr_input_signature(sdrts_reverse_burst_ff_sptr self) -> gr_io_signature_sptr"},
{ (char *)"sdrts_reverse_burst_ff_sptr_output_signature", _wrap_sdrts_reverse_burst_ff_sptr_output_signature, METH_VARARGS, (char *)"sdrts_reverse_burst_ff_sptr_output_signature(sdrts_reverse_burst_ff_sptr self) -> gr_io_signature_sptr"},
{ (char *)"sdrts_reverse_burst_ff_sptr_unique_id", _wrap_sdrts_reverse_burst_ff_sptr_unique_id, METH_VARARGS, (char *)"sdrts_reverse_burst_ff_sptr_unique_id(sdrts_reverse_burst_ff_sptr self) -> long"},
{ (char *)"sdrts_reverse_burst_ff_sptr_to_basic_block", _wrap_sdrts_reverse_burst_ff_sptr_to_basic_block, METH_VARARGS, (char *)"sdrts_reverse_burst_ff_sptr_to_basic_block(sdrts_reverse_burst_ff_sptr self) -> gr_basic_block_sptr"},
{ (char *)"sdrts_reverse_burst_ff_sptr_check_topology", _wrap_sdrts_reverse_burst_ff_sptr_check_topology, METH_VARARGS, (char *)"sdrts_reverse_burst_ff_sptr_check_topology(sdrts_reverse_burst_ff_sptr self, int ninputs, int noutputs) -> bool"},
{ (char *)"sdrts_reverse_burst_ff_sptr_swigregister", sdrts_reverse_burst_ff_sptr_swigregister, METH_VARARGS, NULL},
{ (char *)"reverse_burst_ff", _wrap_reverse_burst_ff, METH_VARARGS, (char *)"reverse_burst_ff(int max_samples) -> sdrts_reverse_burst_ff_sptr"},
{ NULL, NULL, 0, NULL }
};
tôi đi theo kinh nghiệm cũ của tôi với .dll
s và xuất khẩu tất cả các chức năng với một __declspec(dllexport)
đầu đơn giản. Trong Python, tôi cũng có thể gọi số _wrap_sdrts_reverse_burst_ff_sptr___deref__
Tôi đã xuất:
import ctypes
_dll_func_list = ctypes.WinDLL("func.dll")
_reverse_burst_ref = _dll_func_list._wrap_sdrts_reverse_burst_ff_sptr___deref__
Tuy nhiên, đó là điều xa nhất tôi có thể tiếp cận. Khi tôi cố gắng truy cập vào các chức năng phụ trong lớp đó, ví dụ,
_class_ref._wrap_sdrts_reverse_burst_ff_sptr_set_reverse_burst(0)
máy chết tiệt nói với tôi:
'_wrap_sdrts_reverse_burst_ff_sptr_set_reverse_burst' cannot be found.
Khi tôi cố gắng gọi hàm trực tiếp và vượt qua trong một tham số như thế này :
_dll_func_list ._wrap_sdrts_reverse_burst_ff_sptr_set_reverse_burst(0)
Chiếc máy nói
WindowsError: exception: access violation reading 0x00000004
Có ai biết cách truy cập các chức năng được bọc SWIG đã xuất bằng Python không?
Tôi sử dụng tệp python được tạo và nó có trình trợ giúp nhập. Nhưng nó không thành công khi import _my_dll, và nó nói: ImportError: Không có module _my_dll. Tôi đã thêm đường dẫn tuyệt đối vào _my_dll vào cả PYTHONPATH và LD_LIBRARY_PATH, nó sẽ có thể tìm thấy nó. – user1165959
@ user1165959 - bạn cần phải chắc chắn rằng nó được gọi là * chính xác * "_my_dll.dll" sau đó nếu đó là những gì Python than phiền về. Trên các hệ thống Windows, tôi có xu hướng chỉ đặt nó vào thư mục hiện tại tại điểm mà Python được gọi. Dù bằng cách nào ctypes không phải là cách để sửa chữa nó - bạn cần phải sửa chữa đường dẫn + tải vấn đề và nó sẽ tất cả chỉ hoạt động trở lại. – Flexo
Có, nó được gọi là _my_dll.dll chính xác, và tôi cũng đã thử đặt nó dưới c: \ Python27 và nó vẫn không thể tìm thấy nó. Nó chỉ có thể tìm thấy dll khi sử dụng ctypes.WinDLL ("_ my_dll.dll"). Nhưng kể từ khi bạn đề cập nó không phải là cách để làm điều đó, tôi có một cảm giác rằng dll này tôi thực hiện đã không được biên dịch sang một định dạng dễ nhận biết để SWIG. Cách tôi sử dụng swig là: swig -module _my_dll -fvirtual -python -modern -C++ -outdir. -o _my_dll.cxx _my_dll.i và sau đó tôi biên dịch _my_dll.cxx thành một dll cùng với src tôi đã sử dụng để tạo ra _my_dll.i bằng cách sử dụng VC++ 2008 express edition. Bất cứ điều gì tôi đã làm sai? – user1165959