Динамически загружать сборку C # .NET в приложении C ++ Builder

у меня есть Приложение C ++ для Windows, разработанное с помощью RAD Studio (C ++ Builder) XE4. Он имеет несколько плагинов, которые являются DLL (всегда пишутся с RAD Studio), которые динамически загружаются с эта техника.

Теперь в одном из этих плагинов мне нужны возможности отражения. Хотя кажется, что я не могу достичь их с помощью C ++ (требуется отражение в сторонней COM-DLL, которую я не могу изменить), я решил переписать это плагин в C # (который имеет мощные способности отражения), создавая тем самым .Чистая сборка.

Я знаю, что должен выставить сборку через 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*);

Есть ли способ?

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 o .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));
}

Наконец у меня есть Программа C ++ Builder который загружает MyDllBridge.dll и использует его методы, вызывая их, как показано ниже.

//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());
1

Другие решения


По вопросам рекламы [email protected]