6

C と互換性のある関数の簡単な例を示すドキュメントをいくつか読みました。

__declspec(dllexport) MyFunction();

私はそれで大丈夫です。この dll の機能を使用する小さなアプリケーションを作成します。明示的なリンクを使用しました

LoadLibrary() 

関数。C スタイルの関数は問題なく動作します。しかし、クラスを次のように書くと

namespace DllTest
{
class Test
{
public:
    __declspec(dllexport) Test();
    __declspec(dllexport) void Function( int );
    __declspec(dllexport) int getBar(void);
private:
    int bar;
};

}
#endif

それはうまくコンパイルされ、DLLが作成されます。C スタイルの関数を使用している間、私は単に LoadLibrary() および GetProcAddress(...) 関数から関数ポインタを取得していました。

私の以前の使い方は

typedef void (*Function)(int);

int main()
{
   Function _Function;
   HINSTANCE hInstLibrary = LoadLibrary(TEXT("test.dll"));

   if (hInstLibrary)
   {
      _Function = (Function)GetProcAddress(hInstLibrary,"Function");
     if (_Function)
     {
        // use the function

しかし、クラスをインスタンス化する方法がわかりません。明示的リンケージまたは暗黙的リンケージを使用するにはどうすればよいですか?

コードサンプルの助けをいただければ幸いです。

4

2 に答える 2

7

クラスをインスタンス化しようとしている場合は、コンパイル時にその構造を知る必要があります。これを実現するには、インポートされたクラスが再定義する必要のあるインスタンスメソッドを定義する抽象クラスを作成します。例えば:

//interface.h

class TestInterface
{
public:
     virtual void Function( int ) = 0;
     virtual int getBar(void) = 0;
};

その後、DLLにinterface.hを含め、TestInterfaceを継承し、純粋仮想メソッドを再定義できます。

//test.h
namespace DllTest {
    class Test : public TestInterface
    {
    public:
         Test();
         void Function( int );
         int getBar(void);
    private:
        int bar;
    };
};

次に、テストオブジェクトを割り当てるDLLで関数を定義できます。

extern "C" __declspec(dllexport) TestInterface *allocate_test() {
    return new DllTest::Test();
}

そして最後に、DLLをインポートするときに、シンボル「allocate_test」を探して使用します。

TestInterface *(*test_fun)() = (TestInterface *(*test_fun)())GetProcAddress(hInstLibrary,"allocate_test");
TestInterface *test_ptr = test_fun();
test_ptr->Function(12); //use you object
于 2012-02-15T16:13:10.407 に答える
2

まず、これは Microsoft の特徴であることに注意してください。他のシステムには異なるルールが適用されます。

あなたがしたように物事を書くことはうまくいかないか、少なくとも苦痛です. __declspec(dllexport)関数を定義する DLL で使用する必要が__declspec(dllimport)ありますが、別の DLL から関数を呼び出すコードをコンパイルする場合に使用します。これを処理する通常の方法は、DLL を指定する特定のマクロ名を使用して、次のようにすることです。

#ifdef __WIN32
#ifdef MYMODULE_DLL
#define MYMODULE_EXPORT __declspec(dllexport)
#else
#define MYMODULE_EXPORT __declspec(dllimport)
#endif
#else
#define MYMODULE_EXPORT
#endif

これを DLL のすべてのヘッダーに含まれるヘッダーにMYMODULE_DLL配置し、プロジェクトのコマンド ラインで定義します。

また、クラス全体をエクスポートすることもできます:

class MYMODULE_EXPORT DllTest
{
    //  ...
};

これには、クラスのすべての関数と静的メンバーをエクスポートまたはインポートする効果があります。

于 2012-02-15T15:37:46.113 に答える