首页 > 解决方案 > 试图获得与 c++ 类等效的 c#

问题描述

我正在尝试获得与 C++ 类等效的 C#,我在 C++ 方面拥有非常非常基础的知识,所以如果这真的可能的话,我想知道。我尝试了一些东西,但我被卡住了。因此,如果您可以帮助我将这个 c++ 类“解析”为 c#,并向我解释您是如何做到的,或者提供一些可以帮助我的链接。(或者给我一个在我的 c# 项目中使用这个 c++ 类的提示(如果可能由于托管/非托管代码等原因,idk)

C++类:

class GameString
{
public:
    GameString (GameString const&) = delete;
    GameString& operator=(GameString const&) = delete;

    GameString (const std::string &str)
        : _buf (8)
    {
        append (str);
        setHeader (1, length ());
    }

    GameString& operator+=(const std::string &str)
    {
        append (str);
        setHeader (1, length ());

        return *this;
    }

    std::size_t length ()
    {
        return _buf.size () - 8;
    }
    char *str ()
    {
        return reinterpret_cast<char*>(_buf.data () + 8);
    }

private:
    std::vector<unsigned char> _buf;

    void append (const std::string &str)
    {
        for (auto &c : str)
        {
            _buf.push_back (c);
        }
    }

    void setHeader (std::size_t ref, std::size_t len)
    {
        memcpy (&_buf[0], &ref, 4);
        memcpy (&_buf[4], &len, 4);
    }
};

C#类:

class GameString
{
    private List<char> _buf = new List<char>(8);

    public GameString(string str)
    {
        Append(str);
        SetHeader(1, Length());
    }

    private void Append(string str)
    {
        foreach (char c in str)
        {
            _buf.Add(c);
        }
    }

    public int Length()
    {
        return _buf.Count - 8;
    }

    public string Str()
    {
        // return new String(_buf.ToArray());
    }

    private void SetHeader(int rf, int length)
    {
        // memcpy(&_buf[0], &ref, 4);
        // memcpy(&_buf[4], &len, 4);
    }
}

并感谢您的帮助

标签: c#c++visual-c++

解决方案


public class GameString
{
    private MemoryStream buf;

    public GameString(string str)
    {
        buf = new MemoryStream();

        // 8 empty bytes at the beginning
        buf.SetLength(8);
        buf.Position = 8;

        Append(str);
    }

    // Different from C++ implementation. This one is public
    // and updates the SetHeader
    public void Append(string str)
    {
        byte[] utf8 = Encoding.UTF8.GetBytes(str);
        buf.Write(utf8, 0, utf8.Length);
        SetHeader(1, Length);
    }

    public static GameString operator +(GameString gs, string str)
    {
        gs.Append(str);
        return gs;
    }

    // This one is a property instead of being a method
    public int Length { get => (int)buf.Length - 8; }

    // The char *str ()
    public override string ToString()
    {
        return Encoding.UTF8.GetString(buf.GetBuffer(), 8, (int)buf.Length - 8);
    }

    // This one was missing in the C++ implementation. Returns the internal buffer.
    // trimmed to the correct length. Note that it creates a copy!
    public byte[] ToByteArray()
    {
        return buf.ToArray();
    }

    private void SetHeader(int @ref, int len)
    {
        // This could be optimized. Sadly the GetBytes create new
        // arrays as the return value, instead of writing to a 
        // preexisting array.
        byte[] temp = BitConverter.GetBytes(@ref);
        Buffer.BlockCopy(temp, 0, buf.GetBuffer(), 0, temp.Length);

        temp = BitConverter.GetBytes(len);
        Buffer.BlockCopy(temp, 0, buf.GetBuffer(), 4, temp.Length);
    }
}

接着:

var gs = new GameString("Foo");
gs.Append("Bar");
gs.Append("Baz");
gs += "Hello";
gs += "World";
string str = gs.ToString();
byte[] bytes = gs.ToByteArray();

我对 C++ 代码进行了一些更改,在 C# 代码中进行了注释。

我正在使用MemoryStream而不是 aList<>或 a StringBuilderchar在 C# 中是 2 个字节,而在 C 中是 1 个字节,所以在 C# 中你应该使用byte,而不是char.


推荐阅读