Python : CTypes를 사용하여 DLL 기능 액세스 - 기능 별 액세스 * 이름 * 실패

StackOverflow https://stackoverflow.com/questions/1088085

문제

myPythonClient (아래) a ringBell 함수 (DLL에서로드 됨 ctypes). 그러나 액세스를 시도합니다 ringBell 그것을 통해 이름 결과 AttributeError. 왜요?

RingBell.h 포함

namespace MyNamespace
    {
    class MyClass
        {
        public:
            static __declspec(dllexport) int ringBell ( void ) ;
        } ;
    }

RingBell.cpp 포함

#include <iostream>
#include "RingBell.h"
namespace MyNamespace
    {
    int __cdecl MyClass::ringBell ( void )
        {
        std::cout << "\a" ;
        return 0 ;
        }
    }

myPythonClient.py 포함

from ctypes import *
cdll.RingBell[1]() # this invocation works fine
cdll.RingBell.ringBell() # however, this invocation errors out
# AttributeError: function 'ringBell' not found
도움이 되었습니까?

해결책

아마도 C ++ 이름이 컴파일러에 의해 엉망이되고 DLL에서 다음과 같이 내보내지 않기 때문일 수 있습니다. RingBell. 내보낸 이름으로 정확히 같은 이름으로 표시되었는지 확인 했습니까?

다른 팁

C ++ 컴파일러는 네임 스페이스, 클래스 및 서명 (과부하가 가능한 방법)을 반영하기 위해 외부가 보이는 모든 개체의 이름을 관리합니다 (기본 이름뿐만 아니라 기본 이름뿐만 아니라).

이 엉망인을 피하려면 extern "C" 비 C ++ 코드에서 볼 수 있도록 외부 가시적 인 이름에서 (따라서 일부 C ++ 컴파일러는 일부 C ++ 컴파일러가 표준을 확장하지만 일부 이름을 과부하 할 수 없거나 C ++ 표준으로 인라인이 될 수 없습니다. 이 방향).

모두가 지금 작동하고 있습니다 :) 게시물을 요약합니다.

C ++에서 DLL을 쓰십시오 :

// Header
extern "C"
{   // Name in DLL will be "MyAdd" - but you won't be able to find parameters etc...
    __declspec(dllexport) int MyAdd(int a, int b);
}  
// Name will be with lot of prefixes but some other info is provided - IMHO better approach
__declspec(dllexport) int MyAdd2(int a, int b);

//.cpp Code
__declspec(dllexport) int MyAdd(int a, int b)
{   return a+b;
}
__declspec(dllexport) int MyAdd2(int a, int b)
{   return a+b;
} 

그런 다음 프로그램 link.exe를 사용하여 DLL에서 실제 기능 이름을 볼 수 있습니다. Link.exe는 예를 들어 MSVC2010에 있습니다.

c:\program files\microsoft visual studio 10.0\VC\bin\link.exe

사용:

link /dump /exports yourFileName.dll

당신은 다음과 같은 것을 볼 수 있습니다.

ordinal hint RVA      name
      1    0 00001040 ?MyAdd2@@YAHHH@Z = ?MyAdd2@@YAHHH@Z (int __cdecl MyAdd2(int,int))
      2    1 00001030 MyAdd = _MyAdd

그런 다음 파이썬에서는 다음과 같이 가져올 수 있습니다.

import ctypes

mc = ctypes.CDLL('C:\\testDll3.dll')

#mc.MyAdd2(1,2) # this Won't Work - name is different in dll
myAdd2 = getattr(mc,"?MyAdd2@@YAHHH@Z") #to find name use: link.exe /dump /exports fileName.dll 
print myAdd2(1,2)
#p1 = ctypes.c_int (1) #use rather c types
print mc[1](2,3) # use indexing - can be provided using link.exe

print mc.MyAdd(4,5)
print mc[2](6,7) # use indexing - can be provided using link.exe
라이센스 : CC-BY-SA ~와 함께 속성
제휴하지 않습니다 StackOverflow
scroll top