试图得到c#等价于c++;班 我试图得到C++类的C等价物,我有非常非常基础的C++知识,如果真的有可能的话,IDK。我试过一些东西,但我卡住了。所以如果你能帮助我把这个C++类解析成C,解释一下你是怎么做的,或者给我一些帮助我的链接。(或者给我一个提示,把这个C++类应用到我的C项目中(IDK,如果可能的话,因为托管/非托管代码等))

试图得到c#等价于c++;班 我试图得到C++类的C等价物,我有非常非常基础的C++知识,如果真的有可能的话,IDK。我试过一些东西,但我卡住了。所以如果你能帮助我把这个C++类解析成C,解释一下你是怎么做的,或者给我一些帮助我的链接。(或者给我一个提示,把这个C++类应用到我的C项目中(IDK,如果可能的话,因为托管/非托管代码等)),c#,c++,visual-c++,C#,C++,Visual C++,C++类: class GameString { public: GameString (GameString const&) = delete; GameString& operator=(GameString const&) = delete; GameString (const std::string &str) : _buf (8) { append (str); setHe

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);
    }
};
类游戏字符串
{
公众:
GameString(GameString常量&)=删除;
GameString&运算符=(GameString常量&)=删除;
GameString(常量std::string和str)
:(8)
{
追加(str);
setHeader(1,长度());
}
GameString和operator+=(常量std::string和str)
{
追加(str);
setHeader(1,长度());
归还*这个;
}
标准::尺寸/长度()
{
返回_buf.size()-8;
}
char*str()
{
返回重新解释转换(_buf.data()+8);
}
私人:
std::vector _buf;
空附加(常量std::string和str)
{
用于(自动&c:str)
{
_buf.推回(c);
}
}
无效集标题(标准::尺寸\u t参考,标准::尺寸\u t长度)
{
memcpy(&u buf[0],&ref,4);
memcpy(&u buf[4],&len,4);
}
};
C级:

类游戏字符串
{
私有列表_buf=新列表(8);
公共游戏字符串(字符串str)
{
追加(str);
SetHeader(1,Length());
}
私有void追加(字符串str)
{
foreach(str中的字符c)
{
_buf.添加(c);
}
}
公共整数长度()
{
返回_buf.Count-8;
}
公共字符串Str()
{
//返回新字符串(_buf.ToArray());
}
私有void集合头(整数rf,整数长度)
{
//memcpy(&u buf[0],&ref,4);
//memcpy(&u buf[4],&len,4);
}
}

感谢您的帮助,因为标题似乎是一个固定值1和长度,除非我遗漏了什么

你可以很容易地使用和

然后:

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
代替
列表
StringBuilder
char
在C中是2个字节,而在C中是1个字节,所以在C中你应该使用
字节
,而不是
char

,如果你能从C类中详细说明你需要的行为,可能会有所帮助。看起来你本质上是在问de>Str()
应该被实现。这是正确的吗?是的,这就是我要寻找的,我试图从Str()方法和如何生成SetHeader()中获得相同的结果方法,因为它可能会更改值,我不能忽略它。谢谢,但它不是那么简单。我正在尝试将数据包发送到游戏服务器,但数据包中的字符串不能是简单的字符串,这就是为什么创建这个类,以便将经典字符串“转换”为正确的数据包字符串。例如:GameString gamestr的str()方法(“mypacket”)return:mypacketÍÍýý当我将此数据包发送到服务器时,它工作,但当我仅发送“mypacket”时,它不工作。希望您理解,我的英语非常差:/那么服务器想要什么,只是标准ascii字节?
// instantiate
string gameString = "sadasd";

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

// append
gameString += "sdfsfsdfdsf";

// get length again
var newLen = gameString.Length();
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();