private void button6_Click(object sender, EventArgs e) { byte[] inParam = null; IntPtr ptr = IntPtr.Zero; int outlen = -1; string outstr = ""; inParam = Encoding.UTF8.GetBytes("執着不可取"); int ret = Inwhtl_DLL.TestApi(inParam,ref ptr, ref outlen); if(outlen > 0) { outstr = Marshal.PtrToStringAnsi(ptr, (int)outlen); byte[] byt = strToToHexByte(outstr); outstr = Encoding.UTF8.GetString(byt); MessageBox.Show(outstr); } } /// <summary> /// 字符串轉16進制字節數組 /// </summary> /// <param name="hexString"></param> /// <returns></returns> private static byte[] strToToHexByte(string hexString) { hexString = hexString.Replace(" ", ""); if ((hexString.Length % 2) != 0) hexString += " "; byte[] returnBytes = new byte[hexString.Length / 2]; for (int i = 0; i < returnBytes.Length; i++) returnBytes[i] = Convert.ToByte(hexString.Substring(i * 2, 2), 16); return returnBytes; } package main import "C" import ( "e.coding.net/jiftle/inwarehousetool/checktool/chktl" "encoding/hex" "fmt" "os" ) //export Sum func Sum(a int, b int) int { //最簡單的計算和 return a + b } //export TestApi func TestApi(inParam *C.char, outParam **C.char, outlen *C.int) int { // 輸入參數 in := C.GoString(inParam) // 注意事項 s := "1122ABC你" + in bytS := []byte(s) s = hex.EncodeToString(bytS) // 輸出參數 *outParam = C.CString(s) var noutlen int noutlen = len(C.GoString(*outParam)) *outlen = C.int(noutlen) return 0 }
[DllImport("dlltest.dll", CharSet = CharSet.Ansi)]
public static extern int TestApi(byte[] inParam,ref IntPtr outstr, ref int outlen);
注意事項:
很多文章上,使用GoString結構體和Go導出文件.h中對應,經過多次測試,發現程序極易崩潰。
原因可能有以下幾個方面:
1. 結構體的內存映射問題,字段順序需要嚴格對應,字段內存占用長度
2. 返回go string類型,內部不能使用 + 拼接,外部傳入的string參數,否則立即崩潰,無任何提示
結論:
1. 建議使用*C.char作為入參,**C.char作為出參,*C.int提供出參內存占用長度
2. 中文亂碼,go內部采用UTF8編碼,每個中文字符占用3個字節,string默認采用Unicode每個字符4個字節。 傳參之前先做轉換(字符串轉十六進制字符串字符串,互轉)
https://www.cnblogs.com/Leo_wl/p/12075987.html
