包装在C++/CLI中使用本机接口的本机C++代码

Wrapping native C++ code which uses a native interface in C++/CLI

本文关键字:本机 C++ 代码 接口 CLI 包装      更新时间:2023-10-16

我目前正试图包装一个原生C++API的一个部分,该部分使用如下定义的原生C++接口:

#pragma once
class BufferReaderInterface
{
public:
    virtual ~BufferReaderInterface()
    {
    }
    const static int BUFFER_SIZE = 100;
    virtual void ReadNextBuffer(char* buffer) = 0;
};

然后,它被解析器类用于将数据读取到其本地缓冲区中,以便稍后进行如下解析:

#pragma once
#include "BufferReaderInterface.h"
class BufferParser
{
public:
    void ReadNextBuffer(BufferReaderInterface& reader)
    {
        reader.ReadNextBuffer(localBuffer);
    }
    void ParseBuffer()
    {
        // do buffer parsing after ReadNextBuffer()...
    }
private:
    char localBuffer[BufferReaderInterface::BUFFER_SIZE];
};

以下是从文件流读取缓冲区的示例实现(它不一定是文件流,也可以实现为从网络读取):

#pragma once
#include <fstream>
#include "BufferReaderInterface.h"
class FileStreamBufferReader : public BufferReaderInterface
{
public:
    FileStreamBufferReader(std::string filename)
    {
        bufferFile.open(filename.c_str(), 
                        std::ios_base::in | std::ios_base::binary);
        if(!bufferFile)
        {
            throw std::invalid_argument(filename);
        }
    }
    ~FileStreamBufferReader()
    {
        bufferFile.close();
    }
    void ReadNextBuffer(char* buffer)
    {
        bufferFile.read((char *)buffer, BUFFER_SIZE);
    }
private:
    std::ifstream bufferFile;
};

一个简单的用法如下:

BufferReaderInterface* br = new FileStreamBufferReader("test.binary");
BufferParser parser;
parser.ReadNextBuffer(*br);
parser.ParseBuffer();
// use parsed data...
delete br;

我应该如何包装BufferParser类?我试图在上面使用Pimpl习语,但在正确实现ReadNextBuffer(BufferReaderInterface&)函数的托管版本时,我遇到了困难。我曾尝试创建public interface class ManagedBufferReaderInterface,但后来我被卡住了,因为BufferParser采用了本机C++接口,而C++/CLI类无法实现像BufferReaderInterface这样的本机C++界面。以前有人遇到过这种情况吗?

任何建议都将不胜感激!

使用抽象类而不是接口怎么样?

public ref class ManagedBufferReaderInterface abstract
{
private public: // internal 
  BufferReaderInterface * native_interface;
public:
  ManagedBufferReaderInterface(BufferReaderInterface * nativeinterface)
    : native_interface(nativeinterface) 
  { ... }
  //...
};

public ref class ManagedBufferParser
{
  BufferParser * parser;
public:
  ManagedBufferParser()
   : parser(new BufferParser()) 
  { ... }
  void ReadNextBuffer(ManagedBufferReaderInterface ^ reader)
  {
    parser->ReadNextBuffer(reader->native_interface);
  }
  void ParseBuffer()
  {
    parser->ParseBuffer();
  }
//...
};

添加代码:

#include <msclrmarshal_cppstd.h>
public ref class ManagedFileStreamBufferReader : public ManagedBufferReaderInterface
{
public:
  ManagedFileStreamBufferReader(System::String ^ filename)
    : ManagedBufferReaderInterface(new FileStreamBufferReader( msclr::interop::marshal_as<std::string>(filename) ) )
    { ... }
  // ....
};
//Example
ManagedBufferReaderInterface ^ br = gcnew ManagedFileStreamBufferReader("test.binary");
ManagedBufferParser ^ parser = gcnew ManagedBufferParser();
parser->ReadNextBuffer(br);
parser->ParseBuffer();