如何在Win32 C++项目中使用C#dll?

the*_*der 4 c# pinvoke winapi visual-c++

我正在研究一个解决方案,它的大部分核心引擎都是作为Win32 C++开发的(并且与平台无关,也用于OS X),前段时间我们需要从C#调用C++ dll的核心引擎,我能够在C#中加载主解决方案的DLL(在SO的某些线程的帮助下).但是现在我们在Managed C#dll中实现了某些东西,需要在Win32 C++项目中使用它吗?(只提供函数定义和dll)

小智 8

您可以创建托管C++互操作DLL,以充当C#库的包装器.

不幸的是,大多数关于托管C++的教程只解释了如何包装非托管C++以便在C#中使用.但它也可以以其他方式工作.

在本机C++代码中定义抽象接口类,然后在托管C++ DLL中创建一个具体的子类.在方法实现中调用C#对象.

最后,导出一个工厂函数,该函数将实例化实现类并返回本机代码可以使用的基类指针.

这是一个简单的例子:

首先,在本机DLL中定义类接口.

interopclassbase.h

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

现在,您需要创建一个C++/CLI DLL,它允许您在单个程序集中混合本机代码和托管代码.向解决方案添加新的C++项目,并在项目配置中将"公共语言运行时支持"选项设置为" 混合"(/ clr).

一旦你添加了对你的C#库(我们称之为ManagedLibrary)的引用,我们就可以实现interop类:

interopclass.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();
}
Run Code Online (Sandbox Code Playgroud)

现在您只需要从本机项目加载互操作DLL并调用导出的函数.