trying to fix UTF8 strings marshalling

This commit is contained in:
Timerix22 2022-10-30 14:34:50 +06:00
parent cacec5de4b
commit 82f3a47f48
5 changed files with 26 additions and 14 deletions

View File

@ -19,7 +19,7 @@ internal static class DtsodV24Functions
static void TryThrowErrmsg(CharPtr err) static void TryThrowErrmsg(CharPtr err)
{ {
if (err == IntPtr.Zero) return; if (err == IntPtr.Zero) return;
string errmsg = Marshal.PtrToStringUTF8(err); string errmsg = Unmanaged.HGlobalUTF8ToString(err);
Marshal.FreeHGlobal(err); Marshal.FreeHGlobal(err);
throw new Exception(errmsg); throw new Exception(errmsg);
} }
@ -42,7 +42,7 @@ internal static class DtsodV24Functions
{ {
kerep_DtsodV24_serialize(dtsod, out var text, out var err); kerep_DtsodV24_serialize(dtsod, out var text, out var err);
TryThrowErrmsg(err); TryThrowErrmsg(err);
return Marshal.PtrToStringUTF8(text); return Unmanaged.HGlobalUTF8ToString(text);
} }
[DllImport(kereplib, CallingConvention = CallingConvention.Cdecl)] [DllImport(kereplib, CallingConvention = CallingConvention.Cdecl)]
@ -60,7 +60,7 @@ internal static class DtsodV24Functions
internal static void AddOrSet(DtsodPtr dtsod, string key, Unitype value) internal static void AddOrSet(DtsodPtr dtsod, string key, Unitype value)
{ {
IntPtr keyptr = key.ToHGlobalUTF8(); IntPtr keyptr = key.StringToHGlobalUTF8();
kerep_DtsodV24_addOrSet(dtsod, keyptr, value); kerep_DtsodV24_addOrSet(dtsod, keyptr, value);
} }

View File

@ -15,13 +15,12 @@ public struct KVPair
} }
public KVPair(string k, Unitype v) public KVPair(string k, Unitype v)
{ {
key = k.ToHGlobalUTF8(); key = k.StringToHGlobalUTF8();
value = v; value = v;
} }
public override string ToString() public override string ToString()
{ {
throw new NotImplementedException("Marshal.PtrToStringUTF8 can't get non-ascii chars?"); return $"{{{Unmanaged.HGlobalUTF8ToString(key)}, {value}}}";
//return $"{{{Marshal.PtrToStringUTF8(key)}, {value}}}";
} }
} }

View File

@ -48,7 +48,7 @@ public struct Unitype
Float64 = (double) v; Float64 = (double) v;
break; break;
case KerepTypeCode.CharPtr: case KerepTypeCode.CharPtr:
VoidPtr = ((string)v).ToHGlobalUTF8(); VoidPtr = ((string)v).StringToHGlobalUTF8();
break; break;
case KerepTypeCode.AutoarrUnitypePtr: case KerepTypeCode.AutoarrUnitypePtr:
TypeCode = KerepTypeCode.AutoarrUnitypePtr; TypeCode = KerepTypeCode.AutoarrUnitypePtr;
@ -75,7 +75,7 @@ public struct Unitype
case KerepTypeCode.Int64: return Int64; case KerepTypeCode.Int64: return Int64;
case KerepTypeCode.UInt64: return UInt64; case KerepTypeCode.UInt64: return UInt64;
case KerepTypeCode.Float64: return Float64; case KerepTypeCode.Float64: return Float64;
case KerepTypeCode.CharPtr: return Marshal.PtrToStringUTF8(VoidPtr); case KerepTypeCode.CharPtr: return VoidPtr.HGlobalUTF8ToString();
case KerepTypeCode.AutoarrUnitypePtr: return new Autoarr<Unitype>(VoidPtr, false); case KerepTypeCode.AutoarrUnitypePtr: return new Autoarr<Unitype>(VoidPtr, false);
case KerepTypeCode.AutoarrKVPairPtr: return new Autoarr<KVPair>(VoidPtr, false); case KerepTypeCode.AutoarrKVPairPtr: return new Autoarr<KVPair>(VoidPtr, false);
case KerepTypeCode.HashtablePtr: return new DtsodV24(VoidPtr); case KerepTypeCode.HashtablePtr: return new DtsodV24(VoidPtr);
@ -92,7 +92,7 @@ public struct Unitype
case KerepTypeCode.Int64: return $"{{Int64:{Int64}}}"; case KerepTypeCode.Int64: return $"{{Int64:{Int64}}}";
case KerepTypeCode.UInt64: return $"{{UInt64:{UInt64}}}"; case KerepTypeCode.UInt64: return $"{{UInt64:{UInt64}}}";
case KerepTypeCode.Float64: return $"{{Float64:{Float64}}}"; 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.AutoarrUnitypePtr: return $"{{AutoarrUnitypePtr:{VoidPtr.ToString()}}}";
case KerepTypeCode.AutoarrKVPairPtr: return $"{{AutoarrKVPairPtr:{VoidPtr.ToString()}}}"; case KerepTypeCode.AutoarrKVPairPtr: return $"{{AutoarrKVPairPtr:{VoidPtr.ToString()}}}";
case KerepTypeCode.HashtablePtr: return $"{{HashtablePtr:{VoidPtr.ToString()}}}"; case KerepTypeCode.HashtablePtr: return $"{{HashtablePtr:{VoidPtr.ToString()}}}";

View File

@ -39,7 +39,7 @@ public static class TestDtsodV24
foreach (KVPair pair in dtsod) foreach (KVPair pair in dtsod)
{ {
var list = new Autoarr<Unitype>(pair.value.VoidPtr, false); var list = new Autoarr<Unitype>(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) foreach (var el in list)
{ {
Info.Log("h", '\t' + el.ToString()); Info.Log("h", '\t' + el.ToString());

View File

@ -9,10 +9,23 @@ public static class TestPInvoke
public static void TestAll() public static void TestAll()
{ {
DependencyResolver.CopyLibs(); DependencyResolver.CopyLibs();
TestUTF8();
TestPrintf(); TestPrintf();
TestMarshalling(); 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)] [DllImport("kerep", CallingConvention = CallingConvention.Cdecl)]
static extern void pinvoke_print([MarshalAs(UnmanagedType.LPUTF8Str)] string msg); static extern void pinvoke_print([MarshalAs(UnmanagedType.LPUTF8Str)] string msg);
@ -25,14 +38,14 @@ public static class TestPInvoke
} }
[DllImport("kerep", CallingConvention = CallingConvention.Cdecl)] [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() public static unsafe void TestMarshalling()
{ {
Info.Log("c", "---------[TestAutoarr/TestMarshalling]----------"); Info.Log("c", "---------[TestAutoarr/TestMarshalling]----------");
string msg = "ъъ~ 中文"; string msg = "ъъ~ 中文";
test_marshalling(msg, out KVPair* kptr); test_marshalling(msg, out var kptr);
KVPair k = *kptr; KVPair k = *(KVPair*)kptr;
Info.Log("b", k.ToString()); Info.Log("b", k.ToString());
Info.Log("g", "test completed"); Info.Log("g", "test completed");
} }