2012-08-02 4 views
3

Python (2.7)에서 가져올 수있는 DLL을 작성하려고하는데 "작동하게 만드는"데 어려움을 겪고 있습니다. WinDLL() 또는 windll.LoadLibrary()을 사용하여 파이썬에서 라이브러리를로드하고 내 보낸 함수를 테스트하면 비어 있습니다. 내가 TestFunction()에 인수를 추가하면 ValueError이 발생합니다. 많은 인수가있을 수 있습니다 (실제로는 그렇지 않습니다).Python에서 DLL을 사용하고 (ctypes 사용) 작동하지 않습니다.

파이썬 파일 :

from ctypes import * 

x = windll.LoadLibrary('./pymod.dll') 
print x.TestFunction(123) #Should return 123. 

main.h :

#ifndef __MAIN_H__ 
#define __MAIN_H__ 
#include <windows.h> 
#define DLL_EXPORT __declspec(dllexport)  

#ifdef __cplusplus 
extern "C" 
{ 
#endif 

int DLL_EXPORT TestFunction(int data); 

#ifdef __cplusplus 
} 
#endif 

#endif 

MAIN.CPP :

#include "main.h" 

int DLL_EXPORT TestFunction(int x = 0) { 
    return x; 
} 

BOOL WINAPI DllMain(HINSTANCE hinstDLL, DWORD fdwReason, LPVOID lpvReserved) { 
    switch (fdwReason){ 
     case DLL_PROCESS_ATTACH: 
      break; 
     case DLL_PROCESS_DETACH: 
      break; 
     case DLL_THREAD_ATTACH: 
      break; 
     case DLL_THREAD_DETACH: 
      break; 
    } 
    return TRUE; 
} 

해결 된 : 호출 규칙이 잘못되었습니다.

+0

질문/문제에 대한 직접적인 대답은 없지만, 파이썬 모듈을 만들고 싶다면 Boost.Python을 추천합니다. 그냥 생각. – DubyaDubyaDubyaDot

+0

정확한 오류를 붙여 넣을 수 있습니까? 나는 초과/누락 된 바이트 수를 지정해야한다고 생각합니다. –

+0

정확한 오류'ValueError를 입니다 : 아마 너무 많은 인수로 호출 프로 시저 (초과 4 바이트)'당신이 내 대답을 사용할 수 있습니다 – JHolta

답변

6

내 첫 번째 추측은 파이썬이 가정하는 것과 다른 호출 규칙을 사용하고있는 것입니다.

int DLL_EXPORT TestFunction(int data); 

이 선언은 아마 cdecl 호출 규칙이 사용됨을 의미한다; windll을 사용하면 파이썬에서는 stdcall 규칙을 사용해야한다고 생각합니다. 이는 인수가 전달되는 방식을 효과적으로 변경하므로 잘못된 인수를 전달했다고 Python이 판단하게됩니다. 이는 ctypes documentation에 명시되어 있습니다.

그런 경우가 있다면, 당신은 다음 중 하나를 수행 할 수

  1. 변경 (Windows 시스템 DLL이 사용된다) stdcall에 C 코드에서 호출 규칙. MSVC를 사용하는 경우 a doc on developing DLLs입니다.
  2. 파이썬 코드에서 예상하는 호출 규칙을 cdecl으로 변경하십시오. 이는 windll 대신 cdll을 사용하여 수행됩니다.
관련 문제