作者riveranb (River)
看板GameDesign
标题Re: [程式] Unity scripting (native plugin)
时间Tue Dec 26 09:37:38 2017
※ 引述《riveranb (River)》之铭言:
: 标题: [程式] Unity scripting (native plugin)
:
: 以下是我的 sample codes
:
: ==== C++ native plugin部分 ====
: extern "c" declspec(dllexport) void cppfunc( char * tostring, int maxlen)
: {
: std::string source = .... // get texts from opened file
: if(source.length() < maxlen)
: {
: strcpy(tostring, source.c_str());
: }
: }
:
: ==== Unity C# script部分 ====
: [DllImport ("CppPlugin")]
: static extern void cppfunc(StringBuilder tostring, int maxlen);
:
: ......
:
:
: {
: {
: StringBuilder thestring = new StringBuilder(_maxlen); // maxlen = 64
: StringBuilder thestring = new StringBuilder(_maxlen); // maxlen = 64
: while( /** if more in file **/ )
: while( /** if more in file **/ )
: {
: #if METHOD1
: thestring = new StringBuilder(_maxlen); // method 1, always correct
: #else if METHOD2
: thestring.Length = 0; // method 2, get wrong strings after several calls
: #endif
: CppInterop.cppfunc(thestring, _maxlen);
: }
: }
:
: --
: → riveranb: https://goo.gl/okAMCi 12/26 07:32
: 推 cjcat2266: 我的意思是,把Length设成0的时候C#应该是有可能会把 12/26 07:39
: → cjcat2266: 内部buffer切短,导致C++写超出buffer范围而造成错误 12/26 07:39
: → cjcat2266: strcpy本身已经有在字串尾端写上'\0'的行为,理论上不 12/26 07:40
: → cjcat2266: 不需要在C#端另外碰Length 12/26 07:40
: → cjcat2266: 写超出内部buffer范围,看来在你这特定的情况下没有造 12/26 07:41
: → cjcat2266: 成程式当掉,但理论上是有可能当掉的 12/26 07:41
不好意思原文被我编辑到面目全非 XD
感谢 cjcat2266大大堤点!
我懂你的意思了
但经过测试後
如果我完全不动 StringBuilder物件, 直接执行 C++ plugin API的话
StringBuilder 物件内容会没有变动, 维持第一次拿到的string内容
但如果我清空 StringBuilder物件, 再重新设定 Capacity後
就会得到我想要的正确结果
==== snippet ====
StringBuilder thestring = new StringBuilder(_maxlen);
while( more /* if more in file */ )
{
thestring.Length = 0;
thestring.Capacity = _maxlen; // reset capacity
CppInterop.cppfunc(thestring, _maxlen);
// check if more in file
}
====
老实说我也不清楚一直去重新设定 Capacity是不是不好的做法
我会再找找看资料
看是否直接传递 byte [] 去取的字串内容是更好的做法
--
爱打电动到爱上制作游戏
Blog:
http://riveragamer.blogspot.tw/
--
※ 发信站: 批踢踢实业坊(ptt.cc), 来自: 114.40.34.73
※ 文章网址: https://webptt.com/cn.aspx?n=bbs/GameDesign/M.1514252264.A.A06.html
1F:推 cjcat2266: 嗯,是我的话也会用byte[],找不太到StringBuilder传到 12/26 12:46
2F:→ cjcat2266: 之间的转换,让我感觉毛毛的,到底是怎麽把内部buffer 12/26 12:46
3F:→ cjcat2266: 传过去不是很明白,如果有其他人找到资料拜托分享一下 12/26 12:47
4F:→ cjcat2266: 另外,需要同时设定Length和Capacity这样好像没有治本 12/26 12:47
5F:→ cjcat2266: 底层应该还是会重新配置新的buffer记忆体 12/26 12:48
6F:→ cjcat2266: 还有,不更动StringBuilder会维持初次结果也很神秘 12/26 12:50
7F:→ cjcat2266: 可做个实验,在C++把char*位址、初始值和结果值印出来 12/26 12:50
8F:推 wulouise: 找到的资料只有default-marshaling-for-strings 12/30 10:32
9F:→ wulouise: Strinbuilder本身就是一个buffer 所以给buffer之前必须 12/30 10:32
10F:→ wulouise: 设定好她的capacity 12/30 10:32
12F:→ wulouise: 新资料的时候才会reallocate memory XDDD 12/30 10:41
13F:→ wulouise: 过unmanaged code的话她一定不知道 12/30 10:41