2

Visual C++ 2013 で、「プラグイン」プロジェクトから関数をエクスポートしようとしています。

void registerFactories(FactoryRegister<BaseShape> & factoryRegister);

これは、「アプリケーション」プロジェクトによって実行時にリンクされる動的 dll にコンパイルされます。まず、関数ポインター型を定義します。

    typedef void (*RegisterFactoriesType)(FactoryRegister<BaseShape> &);

次のように使用されます。

        auto registerFactories = (RegisterFactoriesType)GetProcAddress(dll, "registerFactories");
        if (!registerFactories) {
            if (verbose) {
                ofLogWarning("ofxPlugin") << "No factories for FactoryRegister<" << typeid(ModuleBaseType).name() << "> found in DLL " << path;
            }
            FreeLibrary(dll);
            return false;
        }

ただし、GetProcAddressNULL を返します。

C 関数を ( を使用して) エクスポートextern "C"し、 を使用して同じ DLL からインポートできることを確認できGetProcAddressますが、C++ 関数のインポートに失敗します。たとえば、これは機能します:

extern "C" {
    OFXPLUGIN_EXPORT void testFunction(int shout);
}

それから

auto testFunction = (TestFunction)GetProcAddress(dll, "testFunction");
if (testFunction) {
    testFunction(5);
}

だから私の推測では、registerFactories. C++ の型を扱う必要があるため、理想的には なしでこれを行いたいと考えていますexport "C"

dumpbin.exe見えるものは次のとおりです。

ファイル examplePlugin.dll のダンプ

ファイルの種類: DLL

Section contains the following exports for examplePlugin.dll

  00000000 characteristics
  558A441E time date stamp Wed Jun 24 14:46:06 2015
      0.00 version
         1 ordinal base
         2 number of functions
         2 number of names

  ordinal hint RVA      name

        1    0 001B54E0 ?registerFactories@@YAXAEAV?$FactoryRegister@VBaseShape@@@ofxPlugin@@@Z = ?registerFactories@@YAXAEAV?$FactoryRegister@VBaseShape@@@ofxPlugin@@@Z (void __cdecl registerFactories(class ofxPlugin::FactoryRegister<class BaseShape> &))
        2    1 001B5520 testFunction = testFunction

Summary

     86000 .data
     8E000 .pdata
    220000 .rdata
      E000 .reloc
      1000 .rsrc
    65D000 .text

編集 :

registerFactoriesは に付ける名前ではありませんGetProcAddress。マングルされた名前を bindump から手動でコピーします。例:

        auto registerFactories = (RegisterFactoriesType)GetProcAddress(dll, "?registerFactories@@YAXPEAV?$FactoryRegister@VBaseShape@@@ofxPlugin@@@Z");

できます!したがって、以下の回答の多くは、実行時にこのマングルされた名前を発見することに関連しています。

4

2 に答える 2