mono - C#傳遞string 到so檔的wchar_t

在windows下

C#和C/C++交換wchar_t的資料時沒有什麼問題

但linux下卻始終出錯

 

正文開始

某一篇文章曾說,你的文字沒有辦法正常顯示,一定是編碼你搞錯了

在windows下,wchar_t是使用 UTF-16LE

而在linux下,wchar_t是使用 UTF-32LE

叮咚!

在C/C++上先寫so檔:

int WCharTest (const wchar_t *MyWord)
{
	int length = wcslen(MyWord);
	printf ("%S\n", MyWord);
	printf ("MyWord Length:%d\n", length);
	for (int i = 0; i < length; i++)
		printf ("%X ", MyWord[i]);
	printf ("\n\n");
	const wchar_t *CWord = L"我是天才,위키백과,イトコ";
	length = wcslen(CWord);
	printf ("%S\n", CWord);
	printf ("MyWord Length:%d\n", length);
	for (int i = 0; i < length; i++)
		printf ("%X ", CWord[i]);
	printf ("\n\n");
	return 0;
}

換C#,因為strings編碼與utf32不同,因此傳送僅能用byte[]及IntPtr

protected void Test (object sender, EventArgs e)
{
    string Str = "我是天才,위키백과,イトコ";

    int Ans;
    //萬一接收方並非是UTF-32LE,可以使用這方式改成UTF-32BE
    //System.Text.UTF32Encoding MyCode = new System.Text.UTF32Encoding (true, false, false);
    byte[] MyWord = System.Text.Encoding.UTF32.GetBytes(Str);
    Ans = Test.WCharTest(MyWord);

    IntPtr MyPtr = Marshal.AllocHGlobal (MyWord.Length);
    Marshal.Copy (MyWord, 0, MyPtr, MyWord.Length);

    Ans = Test.WCharTest (MyPtr);
    Marshal.FreeHGlobal (MyPtr);
}

結果:

好了,大家可以回家了!!

不是!!

有時候會發現,我們送過去的byte在c#下明明正常,但到了so檔後,秀出來的數量卻多了一個

(我在寫這篇時,已找不到是哪個字串會造成這狀況了)

不論如何,建議在c#內組字串時,記得在結尾加上\x00

//這樣送到so後會有溢位的問題
string Str = "我是天才,위키백과,イトコ";
//改成這樣,一勞永逸
string Str = "我是天才,위키백과,イトコ\x00";

 

沒什麼好說的,就是被廠商雷到後

發現是被自己和linux雷到後才會寫這一篇…

若有任何錯誤,請留言告知,會立即修正。