2

我在本机 C++ dll 中有一个引擎,我需要在 C# 项目中使用它。

我对这样做完全陌生,但我已经搜索了几个小时,现在我或多或少地知道如何实现它。我知道我必须编写一个 C# 或 C++/CLI 包装类。

但是我还没有找到如何包装 dll C++ 类的某些方面。该引擎具有 CEntity 类,其中包含以下重要部分:

class CEntity  
{  
    void SendMsg(CEntity *receiver);  
    virtual void ReceiveMsg(MSG msg);
}

其工作原理如下:从 CEntity 继承的类覆盖 ReceiveMsg 函数,实现它想要的,并且继承对象通信发送消息。

我需要在 C# 中使用此功能:从 CEntity“继承”,以 C++ 代码可以调用它的方式覆盖 ReceiveMsg,并能够将消息发送到其他 C#“继承”CEntity 对象抛出 SendMsg C++ 实现。或者换句话说,我需要 C++ 非托管代码调用 C# 托管代码。C++ 代码正在调用 ReceiveMessage(),我需要“覆盖”它或将该调用重定向到 C# 代码中。

是一种在不改变 dll 的情况下做到这一点的方法吗?我无法直接访问 C++ 代码,但如果需要,我可以要求修改 dll。如果不是,那么最少的 dll 修改是什么?

非常感谢

4

1 回答 1

2

这很棘手:

ILogger.h

#pragma once

using namespace System;

namespace AlPDFGenV4 
{
    public interface class ILogger 
    {
    public:
        virtual void Log( String^ ltxt ) = 0;
    };
}

然后 LRLog.h

#pragma once

#include "CMSysString.h"
#include "CLRILogger.h" 
#include <vcclr.h>

using namespace System;

class CNtvLogger;

namespace AlPDFGenV4 
{
    public ref class Logger
    {
    public:
        Logger(void);
        virtual ~Logger(void);

        ILogger^ extlogger;
            CNtvLogger *ntv;

            void Log( String^ txt )
            {
                extlogger->Log( txt );
            }
        };

    }

和 LRLog.cpp

#include "StdAfx.h"
#include "LRLog.h"

using namespace AlPDFGenV4;

Logger::Logger(void)
{
    ntv = new CNtvLogger;
    ntv->clrlogger = this;
} 

Logger::~Logger(void)
{
    delete ntv;
}

class CNtvLogger : CMSysLogger
{
public:
    gcroot<AlPDFGenV4::Logger ^> clrlogger;

protected:
    void _InternalLog( LPCTSTR txt)
    {
        String ^str = gcnew String( txt );

        clrlogger->Log( str );
    }

public:
    bool Init(void * obj)
    {
        return true;
    }

}; 

希望这可以帮助。

在此示例中,Logger 类是一个桥梁,它允许保持本机记录器(由本机代码使用)和接口 ILogger(由托管代码用于传递接收日志输出的类)之间的链接。

您需要在 C++/CLI 中使用这样的类,无需使用这种方法更改 dll。

于 2013-05-14T14:53:42.617 回答