我试图让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);
}
}
感谢您的帮助
答案 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和长度,除非我遗漏了某些东西
您可以轻松使用string
和string.Length();
// instantiate
string gameString = "sadasd";
// get length
var len = gameString.Length();
// append
gameString += "sdfsfsdfdsf";
// get length again
var newLen = gameString.Length();