C++ plugins, LoadLibrary/GetProcAddress needs the exported function in each implementation

340 Views Asked by At

I want to create a plugin architecture. I have a DLL which will serve as the interface and I will then have multiple DLLs for each implementation.

Normalizer.dll-interface DLL

Normalizer.hpp

class INormalizer {
  virtual ~INormalizer() { }
  virtual std::string Normalize(const std::string& input) = 0;
  virtual void Destroy() = 0;
}

NormalizerFactory.hpp

template<typename T> INormalizer* CreateT() { return new T; }

class NormalizerFactory {
public:
  typedef std::map<std::string, INormalizer*(*)()> map_type;
  static INormalizer* CreateInstance(const std::string& name) {
    map_type::iterator it = getMap()->find(name);
    if(it == getMap()->end()) {
      return NULL;
    }
    return it->second();
  }
protected:
  static map_type* getMap() {
    if(!_map) {
      _map = new map_type;
    }
    return _map;
  }
private:
  static map_type* _map;
}

NormalizerFactory.cpp

NormalizerFactory::map_type* NormalizerFactory::_map = NULL;

DerivedRegister.hpp

template<typename T>
class DerivedRegister : NormalizerFactory {
public:
  DerivedRegister(const std::string& name) {
    getMap()->insert(std::make_pair(name, &createT<T>));
  }
}

Normalizer.cpp

extern "C" __declspec(dllexport) INormalizer* __cdecl CreateNormalizer(const std::string& name) {
  return NormalizerFactory::CreateInstance(name);
}

Normalizer.AlphaNumericOnly.dll

AlphaNumericOnly.h

class AlphaNumericOnly : public INormalizer {
public:
  ~AlphaNumericOnly();
  std::string Normalize(const std::string& input) override;
  void Destroy() override;
private:
  static DerivedRegister<AlphaNumericOnly> _reg; 
}

AlphaNumericOnly.cpp

...
DerivedRegister<AlphaNumericOnly> AlphaNUmericOnly::_reg("AlphaNumericOnly");
  • Q How can I force that each implementer also include the DerivedRegister<T> _reg member without adding to the INormalizer interface.

  • Q When building AlphaNumericOnly.dll, the linker complains with LNK2001 for NormalizerFactory::_map. I don't want to have to define the static member NormalizerFactory::_map in each implementation DLL.

The implementation DLLs will be consumed by LoadLibrary/GetProcAddress in the client application. If I load AlphaNumericOnly.dll using LoadLibrary then the call to GetProcAddress(hDll, "CreateNormalizer") fails because the CreateNormalizer function is not exported in this DLL.

  • Q Is there any way I can just create one export file and use it in all implementation DLLs and force all implementers to use this DEF file.
0

There are 0 best solutions below