Как я могу использовать библиотеку dll C# в проекте Win32 C++?


Я работаю над решением, большая часть его ядра разработана как Win32 C++ (и является независимым от платформы и также используется на OS X), некоторое время назад нам нужно было вызвать c++ dll ядра двигателя из C#, и я смог загрузить DLL основного решения в C# (с помощью некоторых потоков здесь на SO). но теперь у нас есть определенные вещи, реализованные в Managed c# dll и нужно использовать его в Win32 C++ project? (и только определения функций и dll предоставляются)

3 4

3 ответа:

Можно создать управляемую библиотеку взаимодействия C++, которая будет действовать как оболочка вокруг библиотеки C#.

Большинство руководств по управляемому C++, к сожалению, только объясняют, как обернуть неуправляемый C++ для использования в C#. Но это может работать и в другую сторону.

Определите абстрактный класс интерфейса в собственном коде C++, а затем создайте конкретный подкласс внутри управляемой библиотеки DLL C++. Вызовите объекты C# в реализациях метода.

Наконец, экспортируйте фабричную функцию, которая создаст экземпляр класс реализации и возвращает указатель базового класса, который может использоваться вашим собственным кодом.

Вот краткий пример:

Во-первых, определите интерфейс класса в вашей собственной DLL.

Interopclassbase.h

class InteropClassBase
{
public:
    virtual void doStuff() = 0;
    virtual int getValue() = 0;
    virtual void getString(CString* outStr) = 0;
};

Теперь вам нужно создать библиотеку DLL C++/CLI, которая позволит вам смешивать машинный и управляемый код в одной сборке. Добавьте новый проект C++ в свое решение и в конфигурации проекта установите параметр "Common Language Runtime Support" в значение смешанный (/clr).

После добавления ссылки на вашу библиотеку C# (которую мы будем называть ManagedLibrary) мы можем реализовать класс взаимодействия:

Класс взаимодействия.cpp

#include "interopclassbase.h"
#include <vcclr.h>

public class InteropClass : public InteropClassBase
{
protected:
    gcroot<ManagedLibrary::ManagedObject^> m_managedObject;

public:
    InteropClass()
    {
        m_managedObject = gcnew ManagedLibrary::ManagedObject();
    }

    virtual void doStuff()
    {
        m_managedObject->doStuff();
    }

    virtual int getValue()
    {
        return m_managedObject->getValue();
    }

    virtual void getString(CString* pOutStr)
    {
        System::String^ managedString = m_managedObject->getString();
        CString nativeString(managedString); // overloaded CString constructor
        if (pOutStr) *pOutStr = nativeString;
    }
};

__declspec(dllexport) InteropClassBase* getImplementationPointer()
{
   return new InteropClass();
}

Теперь вам просто нужно загрузить библиотеку DLL взаимодействия из вашего собственного проекта и вызвать экспортированную функцию.

Одним из решений является com-взаимодействие. Возможно, это единственное решение. Это большая тема. На работе есть большая толстая Синяя книга, которой я пользуюсь. Сотни страниц ничего, кроме COM-взаимодействия.

Короткая версия заключается в том, что вы помечаете некоторые классы и интерфейсы на управляемой стороне и создаете сборки взаимодействия, которые выглядят как библиотеки DLL COM, но на самом деле являются прокси-серверами для управляемых сборок. Сборки взаимодействия регистрируются как библиотеки DLL COM, и вы уходите.

MSDN имеет много информации о оно.

Это, вероятно, хорошая отправная точка. "Предоставление компонентов .NET Framework для COM" http://msdn.microsoft.com/en-us/library/aa720072%28VS.71%29.aspx

Этоможет быть удивительно легко, но постарайтесь, чтобы это было просто.

Для создания управляемого объекта и вызова методов на нем необходимо, чтобы среда CLR была запущена в процессе C++.

В windows можно разместить среду CLR, обратившись к mscoree.dll и размещение CLR в процессе.

Http://msdn.microsoft.com/en-us/magazine/cc163567.aspx
http://msdn.microsoft.com/en-us/library/ms230997.aspx

Для Mono можно встроить среду выполнения Mono в C++ приложение.

Http://www.mono-project.com/Embedding_Mono