我正在尝试获得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);
}
}
感谢你的帮助
发布于 2018-06-18 15:31:04
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
。
发布于 2018-06-17 09:10:52
因为标头看起来是一个固定的值1和长度,除非我遗漏了什么
您可以很容易地使用string
和string.Length();
// instantiate
string gameString = "sadasd";
// get length
var len = gameString.Length();
// append
gameString += "sdfsfsdfdsf";
// get length again
var newLen = gameString.Length();
https://stackoverflow.com/questions/50892840
复制相似问题