Обертывание собственного кода C ++, который использует собственный интерфейс в C ++ / CLI - PullRequest
0 голосов
/ 01 февраля 2012

В настоящее время я застрял, пытаясь обернуть часть собственного API C ++, который использует собственный интерфейс 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 не может реализовать собственный интерфейс C ++, такой как BufferReaderInterface. Кто-нибудь сталкивался с этим раньше?

Буду признателен за любой совет!

1 Ответ

1 голос
/ 02 февраля 2012

Как насчет использования абстрактного класса вместо интерфейса?

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 <msclr\marshal_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();
...