2012-01-23 3 views
5

SWIG 인터페이스와 함께 내 보낸 .dll 공유 라이브러리의 함수를 사용하는 데 문제가 있습니다. Windows .dll에서 SWIG 랩핑 된 함수 사용

Version Info

Python: 2.6.4

Swig: 2.0.4

큰 그림

이다 : 나는 C++를 사용하여 리눅스에서 개발 된 몇 가지 코드를 가지고 SWIG를 사용하여 포장. 나는 C++ 소스를 리눅스에서 .so 오브젝트로 컴파일하고 파이썬에서 .so 라이브러리를 사용했다.

이제이 모든 기능을 창으로 마이그레이션해야하며 Windows의 .so에 해당하는 항목은 .dll입니다. 그래서 모든 C++ 소스 코드를 .dll에 컴파일하고 Python을 통해 액세스하려고했습니다.

정상적인 절차는 다음과 같습니다. C++ 소스를 가지고 SWIG -> 파이썬을 통한 .dll -> 컴파일로 컴파일하십시오.

내가 개발 한 모든 기능이 포함 된 SWIG를 사용하여 생성 된 소스 파일은 대단한 .cxx입니다. 이제이 SWIG 생성 파일을 .dll으로 컴파일하여 나중에 모든 기능을 사용할 수 있습니다. 그러나 .cxx 파일은 모든 함수를 래핑하는 이상한 방법을 사용하며, 어떻게 사용하는지 전혀 모른다.

함수는 다음과 같이 묶여 있습니다. Ssay 나는 클래스가 .cxx 파일의 함수가되며 다음과 같이 정의된다, C++ 클래스는 포장 후, sdrts_reverse_burst_ff라고 있습니다

모두가 아니다
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; 

} 

: 거대한 배열이이 .cxx 파일의 끝 부분 이는 모든 클래스의 기능을 다음과 같이 포함되어 있습니다

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 } 

}; 

나는 .dll의 내 오래된 경험을 따라 간단한 __declspec(dllexport) 머리 모든 기능을 수출했다. 파이썬에서, 나는 또한 내 보낸 _wrap_sdrts_reverse_burst_ff_sptr___deref__를 호출 할 수

import ctypes 

_dll_func_list = ctypes.WinDLL("func.dll") 

_reverse_burst_ref = _dll_func_list._wrap_sdrts_reverse_burst_ff_sptr___deref__ 

을하지만, 그게 내가 접근 할 수있는 가장 먼입니다. 내가 예를 들어, 그 클래스의 하위 기능에 액세스하려고하면

_class_ref._wrap_sdrts_reverse_burst_ff_sptr_set_reverse_burst(0) 

저주 기계는 나에게 말했다 : 내가 직접 함수를 호출하고이 같은 매개 변수를 전달하려고

'_wrap_sdrts_reverse_burst_ff_sptr_set_reverse_burst' cannot be found.

:

_dll_func_list ._wrap_sdrts_reverse_burst_ff_sptr_set_reverse_burst(0) 

기계는 말한다

WindowsError: exception: access violation reading 0x00000004

파이썬을 사용하여 내 보낸 SWIG 래핑 된 함수에 액세스하는 방법을 아는 사람이 있습니까?

답변

2

SWIG는 .cxx 파일 외에도 .py 파일도 생성합니다.당신이 당신의 플랫폼에서 DLL을 내장 (또는 개체를 공유) 한 후에는 파이썬에서 그것을 사용하기 위해 필요한 모든 ModuleName는 당신이 %module를 통해 하나의 모듈을 호출 할 꿀꺽 꿀꺽 말한입니다

import ModuleName 

입니다 명령 줄에서 .i 파일을 호출했을 때.

SWIG에서 생성 된 Python에는 ctypes 등을 사용할 필요가없는 DLL로드를 처리하는 코드가 있습니다. 생성 된 코드는 SWIG에게 파이썬에서 최대한 가깝게 랩핑하도록 요청한 인터페이스와 일치하며 마술처럼 호출을 C++ 측에 전달합니다. sdrts_reverse_burst_ff은 무료 기능이있는 경우

따라서 당신은 할 수 있습니다 :

import ModuleName 

ModuleName.sdrts_reverse_burst_ff() 

당신은 당신이해야 할 것으로 예상 이름 꿀꺽 꿀꺽와 DLL을 빌드 확인해야 - 그것은 예외에서 꽤 분명있을거야 파이썬은 그렇지 않은 경우를 제기합니다. 헤더 기능 만있는 경우가 아니면 sdrts_reverse_burst_ff()이 포함 된 구현과 연결하는 것이 좋습니다.

+0

나는 생성 된 파이썬 파일을 사용하며 가져 오기 도우미가 있습니다. 그러나 _my_dll을 가져올 때 실패하고 다음과 같이 표시됩니다. ImportError : _my_dll이라는 모듈이 없습니다. _my_dll의 절대 경로를 PYTHONPATH와 LD_LIBRARY_PATH에 모두 추가 했으므로 찾을 수 있어야합니다. – user1165959

+0

@ user1165959 - 정확히 * "_my_dll.dll"인지 확인해야합니다. 그렇다면 파이썬이 불평하는 부분입니다. Windows 시스템에서는 파이썬이 호출되는 시점에 현재 디렉토리에 넣는 경향이 있습니다. 어떤 방법 으로든 ctypes가 문제를 해결할 수있는 방법이 아닙니다. 경로 +로드 문제를 해결해야하며 다시 작동합니다. – Flexo

+1

예, 정확히 _my_dll.dll이라고하며 c : \ Python27 아래에 넣으려고했지만 여전히 찾을 수 없습니다. ctypes.WinDLL ("_ my_dll.dll")을 사용할 때만 dll을 찾을 수 있습니다. 그러나 당신이 그것을하는 방법이 아니라고 언급했기 때문에, 나는 내가 만든이 dll이 SWIG에 인식 할 수있는 형식으로 컴파일되지 않았다는 느낌을 가지고 있습니다. swig을 사용하는 방법은 다음과 같습니다. swig -module _my_dll -fvirtual -python -modern -C++ -outdir. -o _my_dll.cxx _my_dll.i 그리고 _my_dll.cxx를 src와 함께 dll에 컴파일했습니다. VC++ 2008 익스프레스 에디션을 사용하여 _my_dll.i를 생성하는 데 사용했습니다. 내가 잘못 한게있어? – user1165959

1

그래서 최종 짧은 대답은 C++ 빌드 윈도우에서 파이썬으로 my_dll을 가져올 수 있도록하기 위해 _my_dll.pyd (안 _my_dll.dll)을 생성해야 할 것으로 보인다. 이것은 빌드 할 리눅스 빌드와는 대조적입니다. _my_dll.so

.dll 파일의 이름을 .pyd로 바꾸기 만하면됩니다. 위의 주석에서 지적한대로 빌드하는 것이 좋습니다.