2011-03-06 15 views
0

C++で実行可能なプラグインシステムで、C++実行可能ファイルがdllを読み込み、GetProcAddress経由でplugin_start(someclass &)を実行しています。C++ Windowsプラグイン - クラスを継承する

私は完全にのdll、およびその逆に関数ポインタを渡す方法を理解し、どのようにDLLは、ヘッダーファイルで定義されたものを使用することができますが、私はDLLは工assがどこにある工assを使用できるようにしたいと思いますsomeclass.hで宣言されていますが、someclass.cppで定義されています。

キャッチは、someclassを呼び出して実行可能ファイルにコンパイルします。つまり、DLLが関数を呼び出そうとすると、リンカーエラーが発生します。私はこれがなぜ、私が理解していないものが私が望むものを達成する方法であるか理解しています。

私はオブジェクトへのポインタと、関数someclass * somefunction *へのポインタを渡して、それをsomeclass - > * somefunction()として呼び出すことができますが、これはすべてにポインタを渡す必要があることを意味しますすべてのクラスで機能します。

これを行う簡単な方法がありますか、Cスタイルの関数と関数ポインタだけを使用し、2つのクラスの間でクラス全体を渡すのを忘れる必要がありますか?

おかげで、
ベン

#ifndef EVENTREGISTRAR_H 
#define EVENTREGISTRAR_H 
#include <vector> 

typedef void (__stdcall *error_callback_t)(const char *error); 

class EventRegistrar 
{ 

public: 
    void OnError(error_callback_t fn); 
    void FireError(const char *error); 


private: 
    std::vector<error_callback_t> errors; 

}; 
#endif 

- CPP

#include "PluginLoader.h" 
void EventRegistrar::OnError(error_callback_t fn) 
{ 
    this->errors.push_back(fn); 
} 

void EventRegistrar::FireError(const char *error) 
{ 
    for (std::vector<error_callback_t>::iterator it = this->errors.begin(); 
     it != this->errors.end(); ++it) 
    { 
     (*it)(error); 
    } 
} 

- DLL

#include "../plugin.h" 
#include <stdio.h> 
void __stdcall error(const char *error) { printf("Error: %s\n",error); } 
extern "C" int __stdcall plugin_start(plugin_start_data& data) 
{ 
    error_callback_t fn = error; 
    data.events.OnError(fn); 
    return LOAD_SUCCESS; 
} 

--Error

Error 1 error LNK2001: unresolved external symbol "public: void __thiscall EventRegistrar::OnError(void (__stdcall*)(char const *))" ([email protected]@@[email protected]@Z) D:\Files\C++ Workspace\BLib\BLib\Example Plugin\main.obj Example Plugin 
+0

DLL境界を越えてSTLオブジェクトを渡すのは悪い考えです。インターフェイスを実装から分離して、これを避けることができます。 – Luke

答えて

0

私はずっと前にこのようなことをしました。私は単純なものを単純に保つために、まっすぐなCインターフェイスを使用しました。

もっと良い方法があるかもしれませんが、私はオブジェクトへのポインタを渡すことがあなたの最高で最も単純なアプローチだと考えています。

+0

私はまだ関数へのポインタを渡す必要がありますが、正しいですか?私はオブジェクトへのポインタ、data-> events-> OnError(fn)を渡してみました。それでもリンカーエラーがあります。 – Ben

+0

いいえ、ヘッダーファイルをコンパイル時に使用できる場合は、オブジェクトへのポインタを渡すだけで済みます。私はあなたがそれらのイベントで何をしているのかについて100%明確ではありません。確かに、それは事を複雑にするでしょう。しかし、ポインタからクラスメンバを参照するときにリンカエラーが発生してはなりません。それは意味をなさない。 –

+0

かなり混乱しています。 EventRegistrarのメンバーを仮想的にすると、私の問題は消えて、すべてが素敵になります。 – Ben