作者riveranb (River)
看板GameDesign
標題[程式] Unity scripting (native plugin)
時間Mon Dec 25 21:50:13 2017
想請教 scripting 使用到 C++ native
plugin相關的問題
我想要從某個 native plugin中拿回處理過的字串內容
看過網路上的資訊知道應該用 StringBuilder
但因為我要重覆這個呼叫過程
所以我想試著使用共用的 StringBuilder 物件
而不是每次都重新 new StringBuilder()
但這樣的話在執行呼叫 native plugin API多次後(可能 20次以上)
我得到的 text內容就會有錯誤(比正確的要短少)
可是如果我每次呼叫 native plugin API都傳入全新的物件 ( 透過 new
StringBuilder() )
我所得到的字串內容就會全部都正確
因為我是第一次做 unmanaged / managed code之間溝通的 programming
所以這部份我不太熟
不知道是過程中哪部分記憶體有出錯
也很想要讓 StringBuilder 物件可保持單一共用就好
也很想要讓 StringBuilder 物件可保持單一共用就好
也很想要讓 StringBuilder 物件可保持單一共用就好
也很想要讓 StringBuilder 物件可保持單一共用就好
也很想要讓 StringBuilder 物件可保持單一共用就好
以下是我的 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);
}
}
--
※ 發信站: 批踢踢實業坊(ptt.cc), 來自: 114.40.34.73
※ 文章網址: https://webptt.com/m.aspx?n=bbs/GameDesign/M.1514209817.A.F64.html
※ 編輯: riveranb (114.40.34.73), 12/25/2017 21:59:58
※ 編輯: riveranb (114.40.34.73), 12/25/2017 22:00:18
1F:推 cjcat2266: 感覺是因為設Length的關係,切buffer長度,然後C++方又12/25 23:51
2F:推 cjcat2266: 感覺是因為設Length的關係,切buffer長度,然後C++方又12/25 23:51
3F:→ cjcat2266: 不知道被切了,最後最後只有寫到C#方有效buffer長度,12/25 23:51
4F:→ cjcat2266: 不知道被切了,最後最後只有寫到C#方有效buffer長度,12/25 23:51
5F:→ cjcat2266: 這樣搞不好會危險?話說strcpy最後已經會加上’/0’不12/25 23:51
6F:→ cjcat2266: 是?那這樣就不用設Length也可以吧?我是沒用過這種nat12/25 23:51
7F:→ cjcat2266: ive溝通方式,我還有個疑問是C#會正確把StringBuilder12/25 23:51
8F:→ cjcat2266: ive溝通方式,我還有個疑問是C#會正確把StringBuilder12/25 23:51
9F:→ cjcat2266: 的buffer位址傳給C++的char*參數嗎?還是其實應該要傳12/25 23:51
10F:→ cjcat2266: 個char[]才對?12/25 23:51
~
※ 編輯: riveranb (42.77.58.61), 12/26/2017 07:14:29
※ 編輯: riveranb (42.77.58.61), 12/26/2017 07:15:02
11F:→ riveranb: 不好意思昨天沒有把codes表示完整,已編輯過12/26 07:16
12F:→ riveranb: METHOD1和METHOD2 不會同時執行,但目的相同12/26 07:17
13F:→ riveranb: METHOD1 是每次都 new StringBuilder,這樣每次拿到的12/26 07:18
14F:→ riveranb: 字串都正確12/26 07:18
15F:→ riveranb: METHOD2 是重覆使用StringBuilder,沒次把之前內容清空12/26 07:19
16F:→ riveranb: 但取回的字串內容會隨執行次數變多而出錯12/26 07:20
17F:→ riveranb: 長度越來越短。比如:12/26 07:20
18F:→ riveranb: SamplesPerPixel => SamplesPer => Sample12/26 07:21
※ 編輯: riveranb (42.77.58.61), 12/26/2017 07:23:39
19F:→ riveranb: 至於透過StringBuilder從 native DLL api 取回字串用法12/26 07:26
20F:→ riveranb: 至於透過StringBuilder從 native DLL api 取回字串用法12/26 07:26
21F:→ riveranb: 是網路上眾多stackoverflow 大神教der,我自己也不熟12/26 07:26
22F:→ riveranb: 熟12/26 07:26
※ 編輯: riveranb (42.77.58.61), 12/26/2017 07:28:16
24F:推 cjcat2266: 我的意思是,把Length設成0的時候C#應該是有可能會把 12/26 07:39
25F:→ cjcat2266: 內部buffer切短,導致C++寫超出buffer範圍而造成錯誤 12/26 07:39
26F:→ cjcat2266: strcpy本身已經有在字串尾端寫上'\0'的行為,理論上不 12/26 07:40
27F:→ cjcat2266: 不需要在C#端另外碰Length 12/26 07:40
28F:→ cjcat2266: 寫超出內部buffer範圍,看來在你這特定的情況下沒有造 12/26 07:41
29F:→ cjcat2266: 成程式當掉,但理論上是有可能當掉的 12/26 07:41