2009-10-27 8 views
1

J'ai DLL, interface sur C++ pour travailler avec he. Dans bcb, msvc cela fonctionne bien. Je veux utiliser des scripts Python pour accéder à la fonction dans cette bibliothèque. Générer un paquet python en utilisant Swig.Violation d'accès sur la fonction d'exécution de la DLL

fichier setup.py

import distutils 
from distutils.core import setup, Extension 

setup(name = "DCM", 
    version = "1.3.2", 
    ext_modules = [Extension("_dcm", ["dcm.i"], swig_opts=["-c++","-D__stdcall"])], 
    y_modules = ['dcm']) 
fichier

de dcm.i

%module dcm 
%include <windows.i> 

%{ 
#include <windows.h> 
#include "../interface/DcmInterface.h" 
#include "../interface/DcmFactory.h" 
#include "../interface/DcmEnumerations.h" 
%} 

%include "../interface/DcmEnumerations.h" 
%include "../interface/DcmInterface.h" 
%include "../interface/DcmFactory.h" 

exécuter ces commandes (python est associée à une extension .py)

setup build 
setup install 

utilisant cette DLL

import dcm 

f = dcm.Factory() #ok 

r = f.getRegistrationMessage() #ok 
print "r.GetLength() ", r.GetLength() #ok 
r.SetLength(0) #access violation 

Sur la dernière chaîne, j'obtiens une violation d'accès. Et j'ai violation d'accès sur chaque fonction en utilisant les paramètres d'entrée.

DcmInterface.h (interface)

class IRegistrationMessage 
{ 
public: 
... 
    virtual int GetLength() const = 0; 
    virtual void SetLength(int value) = 0; 
... 
}; 

uRegistrationMessage.cpp (mise en œuvre dans la DLL)

class TRegistrationMessage : public IRegistrationMessage 
{ 
public: 
... 
virtual int GetLength() const 
    { 
     return FLength; 
    } 
    virtual void SetLength(int Value) 
    { 
     FLength = Value; 
     FLengthExists = true; 
    } 
... 
}; 

usine

DcmFactory.h (en utilisant DLL dans code client)

class Factory 
{ 
private: 
    GetRegistrationMessageFnc GetRegistration; 

bool loadLibrary(const char *dllFileName = "dcmDLL.dll") 
    { 
    ... 
     hDLL = LoadLibrary(dllFileName); 
     if (!hDLL) return false; 
     ... 
     GetRegistration = (GetRegistrationMessageFnc) GetProcAddress(hDLL, "getRegistration"); 
     ... 
    } 
public: 
Factory(const char* dllFileName = "dcmDLL.dll") 
{ 
    loadLibrary(dllFileName); 
} 

IRegistrationMessage* getRegistrationMessage() 
    { 
     if(!GetRegistration) return 0; 
     return GetRegistration(); 
    }; 
}; 
+0

Peut-être que vous pourriez ajouter la ligne qui appelle 'Factory :: SetLength()' à partir du code généré et la déclaration d'origine de 'DcmFactory.h'? –

+0

... arg1 = reinterpret_cast (argp1); ecode2 = SWIG_AsVal_int (obj1, &val2); if (! SWIG_IsOK (ecode2)) { SWIG_exception_fail (SWIG_ArgError (ecode2), "dans la méthode « "IRegistrationMessage_SetLength" "', argument " "2"" de type" "int" "'"); } arg2 = static_cast < int > (val2); (arg1) -> SetLength (arg2); ... – Xeningem

Répondre

0

Je trouve un bug. Si vous en utilisant DLL, vous devez écrire les conventions d'appel sous une forme explicite comme ceci:

class IRegistrationMessage 
{ 
public: 
... 
    virtual int _cdecl GetLength() const = 0; 
    virtual void _cdecl SetLength(int value) = 0; 
... 
}; 

J'append les conventions d'appel et maintenant tout va bien de travail.

Questions connexes