c#調用dll介面傳遞utf-8字串方法

來源:互聯網
上載者:User

標籤:images   調用dll   c++   簡體   lis   cee   c#   read   imp   

1. 起

VCU10之視頻下載模組,採用純python實現,c++代碼調用pythonrun.h配置python運行環境啟動python模組,以使介面UI能夠使用其中功能。

棘手問題!用去一天時間反覆列印日誌,驗證所傳字串區別,以期望發現問題定位問題,直至下班前始有靈感。

驗證發現,非中文字元可以正常下載,中文字元下載解析失敗,當時即想到可能是字串不統一所致,就在python代碼中做字串轉換處理,均不奏效。

原介面封裝代碼如下:

    [DllImport("VideoDownloader", CallingConvention = CallingConvention.Cdecl, CharSet = CharSet.Ansi)]    private extern static bool VDDownload(IntPtr instance,string savePath,string imageSavePath,        string quality, string ext, string subtitleLang);

比如傳savePath為[d:\vcu新],dll調用python模組,則列印日誌為:

dir: d:\kvd新, code: ‘d:\\kvd\xd0\xc2‘

而直接運行python代碼,其輸出卻是:

dir: d:\kvd新, code: ‘d:\\kvd\xe6\x96\xb0‘

用c#建Demo驗知\xd0\xc2為[新]字的gb2312編碼,\xe6\x96\xb0為[新]字的utf-8編碼。

 

 

2、字串編碼

Win7 64位簡體中文版中c#的預設編碼:

做如此簡單驗證,發現其預設編碼為gb2312;而所用python代碼,為兼顧中文等多位元組字元,預設採用utf-8編碼。

問題大抵就在這裡了,dll介面字串,改為utf-8字串傳遞。但c#內建沒有utf-8封裝器,自訂實現它。

 

 

3、UTF8Marshaler

    //介面資料為utf-8編碼所設定    public class UTF8Marshaler : ICustomMarshaler    {        public void CleanUpManagedData(object managedObj)        {        }        public void CleanUpNativeData(IntPtr pNativeData)        {            Marshal.FreeHGlobal(pNativeData);        }        public int GetNativeDataSize()        {            return -1;        }        public IntPtr MarshalManagedToNative(object managedObj)        {            if (object.ReferenceEquals(managedObj, null))                return IntPtr.Zero;            if (!(managedObj is string))                throw new InvalidOperationException();            byte[] utf8bytes = Encoding.UTF8.GetBytes(managedObj as string);            IntPtr ptr = Marshal.AllocHGlobal(utf8bytes.Length + 1);            Marshal.Copy(utf8bytes, 0, ptr, utf8bytes.Length);            Marshal.WriteByte(ptr, utf8bytes.Length, 0);            return ptr;        }        public object MarshalNativeToManaged(IntPtr pNativeData)        {            if (pNativeData == IntPtr.Zero)                return null;            List<byte> bytes = new List<byte>();            for (int offset = 0; ; offset++)            {                byte b = Marshal.ReadByte(pNativeData, offset);                if (b == 0) break;                else bytes.Add(b);            }            return Encoding.UTF8.GetString(bytes.ToArray(), 0, bytes.Count);        }        private static UTF8Marshaler instance = new UTF8Marshaler();        public static ICustomMarshaler GetInstance(string cookie)        {            return instance;        }    }

 

 

4、更新介面字串封送樣式

    [DllImport("VideoDownloader", CallingConvention = CallingConvention.Cdecl, CharSet = CharSet.Ansi)]    private extern static bool VDDownload(IntPtr instance,        [MarshalAs(UnmanagedType.CustomMarshaler, MarshalTypeRef = typeof(UTF8Marshaler))]        string savePath,        [MarshalAs(UnmanagedType.CustomMarshaler, MarshalTypeRef = typeof(UTF8Marshaler))]        string imageSavePath,        string quality, string ext, string subtitleLang);

驗證工作OK!運行效果如下:

至此,一個技術痛點解決,記錄於此。

c#調用dll介面傳遞utf-8字串方法

相關文章

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.