I got third-party native C library.so
in my .NET Core 3.1 application under linux os (debian).
There was identical library.dll
under Windows with .NET SDK for it.
The Windows and linux C-libraries have the same methods signatures, I had check them.
With the help of dotpeek I adopt the code of sdk to linux app:
[DllImport("library.so", CharSet = CharSet.Ansi, CallingConvention = CallingConvention.StdCall)]
internal static extern uint FindEntites(out FoundResultsStruct foundResult);
...
internal ArrayList FillCollection()
{
var innerList = new ArrayList();
FoundResultsStruct results;
var code = FindEntites(out results);
IntPtr ptr = results.Value;
if (ptr == IntPtr.Zero)
throw new Exception();
int num = Marshal.SizeOf(typeof(FoundEntityStruct));
for (long index = 0; index < results.Count; ++index)
{
innerList.Add(new CollectionEntity(Marshal.PtrToStructure<FoundEntityStruct>(ptr))); //point of Exception
ptr = (IntPtr)((long)ptr + (long)num);
}
return innerList;
}
When I run the code, it throws the exception at point of Exception
at the index
variable equals 0, the first element of collection:
No mapping for the Unicode character exists in the target multi-byte code page. (0x80070459)
System.ArgumentOutOfRangeException: No mapping for the Unicode character exists in the target multi-byte code page. (0x80070459)
at System.Runtime.InteropServices.Marshal.PtrToStructureHelper(IntPtr ptr, Object structure, Boolean allowValueClasses)
at System.Runtime.InteropServices.Marshal.PtrToStructureHelper(IntPtr ptr, Type structureType)
at System.Runtime.InteropServices.Marshal.PtrToStructure(IntPtr ptr, Type structureType)
at System.Runtime.InteropServices.Marshal.PtrToStructure[T](IntPtr ptr)
at MyApp.EntitesCollection.FillCollection() in C:\Projects\MyApp\EntitesCollection.cs:line 77
I suppose it cause native C-library interacts with ANSI encoding instead of UTF-8.
I had try to change the CharSet
of DllImport
attribute to CharSet.Ansi/Unicode/Auto
- it has no effect.
Found this, looks like it's similar case, but didn't understand the solution.
Any ideas?
(IntPtr)((long)ptr + (long)num)
looks a little bit strange to me and can be replaced by something likeIntPtr.Add(ptr, num);
. I don't think that it can cause the problem though.FoundResultsStruct
in both native and C#.