1

彼と一緒に作業するためのDLL、C++のインターフェイスがあります。bcb、msvcでは正常に動作します。Pythonスクリプトを使用して、このライブラリの関数にアクセスしたいと思います。Swigを使用してpython-packageを生成します。

ファイル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();
    };
};
4

1 に答える 1

0

バグを見つけました。DLLを使用する場合は、呼び出し規約を次のような明示的な形式で記述する必要があります。

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

呼び出し規約を追加すると、すべて正常に機能します。

于 2009-11-10T09:27:36.743 に答える