2015-09-10 222 views
0

我有一個用RAD Studio(C++ Builder)XE4開發的C++ Windows應用程序。它有一些插件,這些插件是用this technique動態加載的DLL(總是用RAD Studio編寫)。在C++ Builder應用程序中動態加載C#.NET程序集

現在在這個插件中,我需要反射功能。雖然看起來我無法用C++來實現它們(反射需要在我無法修改的第三方COM DLL上),但我決定在C#(它具有強大的反射功能)中重寫這個插件,從而創建了一個.NET程序集

我知道我應該通過COM公開程序集,但我不能(我們不想改變主應用程序加載所有DLL的方式)。

我的目標是與類似下面的動態加載.NET程序集並調用其功能(比如這裏我們稱之爲SetParam功能),就像我與其他插件做。

//load DLL 
HINSTANCE handleDll = LoadLibraryW("C:/Path/to/the/assembly.dll"); 
//get reference to the function 
void* ptr = GetProcAddress(handleDll, "_SetParam"); 
ptr_SetParam ptrFunc = reinterpret_cast<ptr_SetParam>(ptr); 
//invoke function 
int result = (*ptrFunc)(String("mykey").c_str(), String("myvalue").c_str()); 

其中ptr_SetParam被定義爲

typedef int(*ptr_SetParam)(const wchar_t*, const wchar_t*); 

有沒有辦法?

+2

[有方法](http://stackoverflow.com/questions/17127825/c-sharp-unmanaged-exports)將非託管導出插入C#程序集。吉塞克的工具得到了很多應用。請注意,這幾乎從來不是一個嚴重的錯誤,它規模很小,異常極難診斷。 –

回答

0

感謝@ HansPassant的評論我找到了一種方法。

我創建了以下Visual Studio項目。

MyDllCore .NET程序集項目,用C#或任何其他.NET語言編寫。在這裏,我有我的託管類,如下所述,組裝的真正邏輯被實現。

using System; 
using System.Collections.Generic; 
//more usings... 

namespace MyNamespace 
{ 
    public class HostDllB1 
    { 
     private Dictionary<string, string> Parameters = new Dictionary<string, string>(); 

     public HostDllB1() 
     { 
     } 

     public int SetParam(string name, string value) 
     { 
      Parameters[name] = value; 
      return 1; 
     } 
    } 
} 

MyDllBridge DLL工程,寫在C++/CLI,與/clr編譯器選項。它只是一個「橋樑」項目,它對MyDllCore項目具有依賴性,並且只有一個.cpp .h文件,如下所示,其中將加載DLL的程序的方法映射到.NET程序集中的方法。

using namespace std; 
using namespace System; 
using namespace MyNamespace; 
//more namespaces... 

#pragma once 
#define __dll__ 
#include <string.h> 
#include <wchar.h> 
#include "vcclr.h" 
//more includes... 

//References to the managed objects (mainly written in C#) 
ref class ManagedGlobals 
{ 
public: 
    static MyManagedClass^ m = gcnew MyManagedClass; 
}; 

int SetParam(const wchar_t* name, const wchar_t* value) 
{ 
    return ManagedGlobals::m->SetParam(gcnew String(name), gcnew String(value)); 
} 

最後我有一個加載MyDllBridge.dll和使用它的方法調用它們就像下一個C++ Builder程序

//load DLL 
HINSTANCE handleDll = LoadLibraryW("C:/Path/to/the/MyDllBridge.dll"); 
//get reference to the function 
void* ptr = GetProcAddress(handleDll, "SetParam"); 
ptr_SetParam ptrFunc = reinterpret_cast<ptr_SetParam>(ptr); 
//invoke function 
int result = (*ptrFunc)(String("mykey").c_str(), String("myvalue").c_str()); 
相關問題