试图获得c#等价的c ++类

时间:2018-06-17 00:49:47

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

我试图让C#等同于C ++课程,我在C ++中具有非常基础的知识,所以如果真的有可能,那就是idk。我尝试了一些东西,但我被卡住了。所以,如果你能帮助我解析"这个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:

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);
    }
}

感谢您的帮助

2 个答案:

答案 0 :(得分:1)

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代替List<>StringBuilder。 C#中的char是2个字节,而在C中它是1个字节,所以在C#中你应该使用byte,而不是char

答案 1 :(得分:0)

由于标题似乎是固定值1和长度,除非我遗漏了某些东西

您可以轻松使用stringstring.Length();

// instantiate
string gameString = "sadasd";

// get length
var len = gameString.Length();

// append
gameString += "sdfsfsdfdsf";

// get length again
var newLen = gameString.Length();