2009-10-27 134 views
1

我有DLL,C++接口與他一起工作。在bcb中,msvc工作正常。我想使用Python腳本來訪問這個庫中的函數。 使用Swig生成python-package。從DLL運行函數訪問衝突

文件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']) 

文件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" 

運行這些指令(Python是具有延伸的.py相關聯)

setup build 
setup install 

使用這個DLL

import dcm 

f = dcm.Factory() #ok 

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

在最後一個字符串我得到訪問衝突。我使用輸入參數訪問每個函數。

DcmInterface.h(接口)

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

uRegistrationMessage.cpp(在DLL實現)

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

DcmFactory.h(使用DLL中客戶代碼)

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

也許你可以從生成的代碼中添加調用'Factory :: SetLength()'的行,並從'DcmFactory.h'中添加原始聲明? – 2009-10-27 18:54:05

+0

... arg1 = reinterpret_cast (argp1); ecode2 = SWIG_AsVal_int(OBJ1,&val2); 如果(!SWIG_IsOK( 「在方法「」'IRegistrationMessage_SetLength「 」 '參數 「 」2「,」 類型的「' 」INT「 ecode2)){ SWIG_exception_fail(SWIG_ArgError(ecode2), 「'」); } arg2 = static_cast < int >(val2); (arg1) - > SetLength(arg2); ... – Xeningem 2009-10-28 08:14:35

回答

0

我發現bug。 如果您使用DLL,您必須編寫調用約定在一個明確的形式是這樣的:

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

我追加調用約定,現在一切工作的罰款。