2016-07-01 2 views
0

J'accède à une DLL C++ en utilisant Python Ctypes sur Windows 7. J'ai la documentation pour la DLL, mais je ne peux pas l'ouvrir. J'essaie d'utiliser une fonction C++ qui accepte une fonction qui, à son tour, prend un entier non signé et un pointeur vide. Voici un exemple de code court qui ne parvient:Ctypes - Passer un pointeur vide à partir de Python

import ctypes 
import os 

root = os.path.dirname(__file__) 
lib = ctypes.WinDLL(os.path.join(root, 'x86', 'toupcam.dll')) #works 

cam = lib.Toupcam_Open(None) #works 

def f(event, ctx): #Python version of function to pass in 
    pass 

#converting Python function to C function: 
#CFUNTYPE params: return type, parameter types 
func = ctypes.CFUNCTYPE(None, ctypes.c_uint, ctypes.c_void_p)(f) 

res = lib.Toupcam_StartPullModeWithCallback(cam, func) #fails 

Chaque fois que je lance ce code que je reçois cette erreur sur la dernière ligne:

OSError: exception: access violation writing 0x002CF330. 

Je ne sais pas vraiment comment aborder cette question, étant donné que c'est une erreur C++ pas une erreur Python. Je pense que cela a à voir avec mon pointeur vide, puisque les erreurs similaires que j'ai trouvées en ligne pour C++ étaient liées au pointeur. Y at-il quelque chose qui ne va pas avec le pointeur vide de Ctypes, ou est-ce que je fais quelque chose de mal?

+1

Un rapide google montre que 'Toupcam_StartPullModeWithCallback' prend trois arguments: caméra, rappel, contexte. http://www.webastro.net/forum/archive/index.php/t-138355.html – kfsone

Répondre

0

Vous devez déclarer les types d'argument des fonctions que vous appelez en utilisant argtypes. Comme je ne connais pas votre API exacte, voici un exemple:

code de Windows DLL C avec un rappel:

typedef void (*CB)(int a); 

__declspec(dllexport) void do_callback(CB func) 
{ 
    int i; 
    for(i=0;i<10;++i) 
     func(i); 
} 

code Python:

from ctypes import * 

# You can use as a Python decorator. 
@CFUNCTYPE(None,c_int) 
def callback(a): 
    print(a) 

# Use CDLL for __cdecl calling convention...WinDLL for __stdcall. 
do_callback = CDLL('test').do_callback 
do_callback.restype = None 
do_callback.argtypes = [CFUNCTYPE(None,c_int)] 

do_callback(callback) 

Sortie:

0 
1 
2 
3 
4 
5 
6 
7 
8 
9