From 82f3a47f4858655b65e543b3cba196d144482e5b Mon Sep 17 00:00:00 2001 From: Timerix22 Date: Sun, 30 Oct 2022 14:34:50 +0600 Subject: [PATCH] trying to fix UTF8 strings marshalling --- DTLib.Dtsod/V24/DtsodV24Functions.cs | 6 +++--- DTLib.Dtsod/V24/KerepTypes/KVPair.cs | 5 ++--- DTLib.Dtsod/V24/KerepTypes/Unitype.cs | 6 +++--- DTLib.Tests/Dtsod/TestDtsodV24.cs | 2 +- DTLib.Tests/Dtsod/TestPInvoke.cs | 21 +++++++++++++++++---- 5 files changed, 26 insertions(+), 14 deletions(-) diff --git a/DTLib.Dtsod/V24/DtsodV24Functions.cs b/DTLib.Dtsod/V24/DtsodV24Functions.cs index 16ea055..b08f934 100644 --- a/DTLib.Dtsod/V24/DtsodV24Functions.cs +++ b/DTLib.Dtsod/V24/DtsodV24Functions.cs @@ -19,7 +19,7 @@ internal static class DtsodV24Functions static void TryThrowErrmsg(CharPtr err) { if (err == IntPtr.Zero) return; - string errmsg = Marshal.PtrToStringUTF8(err); + string errmsg = Unmanaged.HGlobalUTF8ToString(err); Marshal.FreeHGlobal(err); throw new Exception(errmsg); } @@ -42,7 +42,7 @@ internal static class DtsodV24Functions { kerep_DtsodV24_serialize(dtsod, out var text, out var err); TryThrowErrmsg(err); - return Marshal.PtrToStringUTF8(text); + return Unmanaged.HGlobalUTF8ToString(text); } [DllImport(kereplib, CallingConvention = CallingConvention.Cdecl)] @@ -60,7 +60,7 @@ internal static class DtsodV24Functions internal static void AddOrSet(DtsodPtr dtsod, string key, Unitype value) { - IntPtr keyptr = key.ToHGlobalUTF8(); + IntPtr keyptr = key.StringToHGlobalUTF8(); kerep_DtsodV24_addOrSet(dtsod, keyptr, value); } diff --git a/DTLib.Dtsod/V24/KerepTypes/KVPair.cs b/DTLib.Dtsod/V24/KerepTypes/KVPair.cs index e3e0fc0..b421dd9 100644 --- a/DTLib.Dtsod/V24/KerepTypes/KVPair.cs +++ b/DTLib.Dtsod/V24/KerepTypes/KVPair.cs @@ -15,13 +15,12 @@ public struct KVPair } public KVPair(string k, Unitype v) { - key = k.ToHGlobalUTF8(); + key = k.StringToHGlobalUTF8(); value = v; } public override string ToString() { - throw new NotImplementedException("Marshal.PtrToStringUTF8 can't get non-ascii chars?"); - //return $"{{{Marshal.PtrToStringUTF8(key)}, {value}}}"; + return $"{{{Unmanaged.HGlobalUTF8ToString(key)}, {value}}}"; } } \ No newline at end of file diff --git a/DTLib.Dtsod/V24/KerepTypes/Unitype.cs b/DTLib.Dtsod/V24/KerepTypes/Unitype.cs index 6845e72..3e38ea4 100644 --- a/DTLib.Dtsod/V24/KerepTypes/Unitype.cs +++ b/DTLib.Dtsod/V24/KerepTypes/Unitype.cs @@ -48,7 +48,7 @@ public struct Unitype Float64 = (double) v; break; case KerepTypeCode.CharPtr: - VoidPtr = ((string)v).ToHGlobalUTF8(); + VoidPtr = ((string)v).StringToHGlobalUTF8(); break; case KerepTypeCode.AutoarrUnitypePtr: TypeCode = KerepTypeCode.AutoarrUnitypePtr; @@ -75,7 +75,7 @@ public struct Unitype case KerepTypeCode.Int64: return Int64; case KerepTypeCode.UInt64: return UInt64; case KerepTypeCode.Float64: return Float64; - case KerepTypeCode.CharPtr: return Marshal.PtrToStringUTF8(VoidPtr); + case KerepTypeCode.CharPtr: return VoidPtr.HGlobalUTF8ToString(); case KerepTypeCode.AutoarrUnitypePtr: return new Autoarr(VoidPtr, false); case KerepTypeCode.AutoarrKVPairPtr: return new Autoarr(VoidPtr, false); case KerepTypeCode.HashtablePtr: return new DtsodV24(VoidPtr); @@ -92,7 +92,7 @@ public struct Unitype case KerepTypeCode.Int64: return $"{{Int64:{Int64}}}"; case KerepTypeCode.UInt64: return $"{{UInt64:{UInt64}}}"; case KerepTypeCode.Float64: return $"{{Float64:{Float64}}}"; - case KerepTypeCode.CharPtr: return $"{{CharPtr:{Marshal.PtrToStringUTF8(VoidPtr)}}}"; + case KerepTypeCode.CharPtr: return $"{{CharPtr:{Unmanaged.HGlobalUTF8ToString(VoidPtr)}}}"; case KerepTypeCode.AutoarrUnitypePtr: return $"{{AutoarrUnitypePtr:{VoidPtr.ToString()}}}"; case KerepTypeCode.AutoarrKVPairPtr: return $"{{AutoarrKVPairPtr:{VoidPtr.ToString()}}}"; case KerepTypeCode.HashtablePtr: return $"{{HashtablePtr:{VoidPtr.ToString()}}}"; diff --git a/DTLib.Tests/Dtsod/TestDtsodV24.cs b/DTLib.Tests/Dtsod/TestDtsodV24.cs index ce5ba70..f5d829b 100644 --- a/DTLib.Tests/Dtsod/TestDtsodV24.cs +++ b/DTLib.Tests/Dtsod/TestDtsodV24.cs @@ -39,7 +39,7 @@ public static class TestDtsodV24 foreach (KVPair pair in dtsod) { var list = new Autoarr(pair.value.VoidPtr, false); - Info.Log("b", pair.key.ToStringUTF8(), "w", $" length: {list.Length}"); + Info.Log("b", pair.key.HGlobalUTF8ToString(), "w", $" length: {list.Length}"); foreach (var el in list) { Info.Log("h", '\t' + el.ToString()); diff --git a/DTLib.Tests/Dtsod/TestPInvoke.cs b/DTLib.Tests/Dtsod/TestPInvoke.cs index d8f2804..f95b199 100644 --- a/DTLib.Tests/Dtsod/TestPInvoke.cs +++ b/DTLib.Tests/Dtsod/TestPInvoke.cs @@ -9,10 +9,23 @@ public static class TestPInvoke public static void TestAll() { DependencyResolver.CopyLibs(); + TestUTF8(); TestPrintf(); TestMarshalling(); } - + + static public void TestUTF8() + { + Info.Log("c", "--------[TestPInvoke/TestUTF8]--------", "b", ""); + IntPtr ptr; + string str="_$\"\\\\'''\ta ыыы000;2;=:%d;```"; + for(int i=0; i<1000; i++) + { + ptr = Unmanaged.StringToHGlobalUTF8(str); + str = Unmanaged.HGlobalUTF8ToString(ptr); + } + Info.Log("y", str); + } [DllImport("kerep", CallingConvention = CallingConvention.Cdecl)] static extern void pinvoke_print([MarshalAs(UnmanagedType.LPUTF8Str)] string msg); @@ -25,14 +38,14 @@ public static class TestPInvoke } [DllImport("kerep", CallingConvention = CallingConvention.Cdecl)] - static extern unsafe void test_marshalling([MarshalAs(UnmanagedType.LPUTF8Str)] string text, out KVPair* k); + static extern unsafe void test_marshalling([MarshalAs(UnmanagedType.LPUTF8Str)] string text, out IntPtr kptr); public static unsafe void TestMarshalling() { Info.Log("c", "---------[TestAutoarr/TestMarshalling]----------"); string msg = "ъъ~ 中文"; - test_marshalling(msg, out KVPair* kptr); - KVPair k = *kptr; + test_marshalling(msg, out var kptr); + KVPair k = *(KVPair*)kptr; Info.Log("b", k.ToString()); Info.Log("g", "test completed"); }