[英]How can I override default encoding when marshalling strings?
I have a Delphi 2007 DLL with this export:我有一个 Delphi 2007 DLL 这个出口:
function TestSignString(s, Sign: PChar): LongBool; stdcall;
I am calling it in .NET Core v7 C# using this import:我使用此导入在 .NET Core v7 C# 中调用它:
[DllImport(@"LibraryName.dll")]
[return:MarshalAs(UnmanagedType.Bool)]
internal static extern bool TestSignString(string s, string sign);
I am passing s
and sign
params, when the run-time system has default encoding (EXPECTED) WIN1250 everything goes fine as expected, however when it's not, there's default system encoding involved and passed chars are encoded using default encoding (for example to WIN1252).我正在传递s
和sign
参数,当运行时系统具有默认编码(预期)WIN1250 时一切正常).
So my question is, how to override default encoding when marshaling strings in C#?所以我的问题是,在 C# 中封送字符串时如何覆盖默认编码? I mean both ways - as a input params and output as well, please.我的意思是两种方式 - 作为输入参数和 output 也请。
I have tried altering the import to:我尝试将导入更改为:
[DllImport(@"LockBoxLibrary.dll", CharSet = CharSet.Ansi)]
but no luck, I am missing code page (1250) specification.但运气不好,我缺少代码页 (1250) 规范。
I have a "dirty" solution as it's probably memory leaking.我有一个“脏”解决方案,因为它可能正在泄漏 memory。 Let me know if you know better way, please.如果您知道更好的方法,请告诉我。 I have two extension methods for string conversion to nint and vice versa.我有两种将字符串转换为 nint 的扩展方法,反之亦然。
private static string FromAnsiPtrToUtf8Str(this nint n)
{
var length = 0;
while (Marshal.ReadByte(n + length) != 0)
{
length++;
}
var strbuf = new byte[length];
Marshal.Copy(n, strbuf, 0, length);
return Encoding.GetEncoding(1250).GetString(strbuf);
}
private static nint FromUtf8StrToAnsiPtr(this string s) => GCHandle.Alloc(Encoding.GetEncoding(1250).GetBytes(s), GCHandleType.Pinned).AddrOfPinnedObject();
Import changed to: private static extern bool TestSignString(nint s, nint sign);
导入更改为: private static extern bool TestSignString(nint s, nint sign);
Method call: TestSignString(s.FromUtf8StrToAnsiPtr(), sign.FromUtf8StrToAnsiPtr());
方法调用: TestSignString(s.FromUtf8StrToAnsiPtr(), sign.FromUtf8StrToAnsiPtr());
Try to change TestSignString
to take a UTF-16 string, or introduce a widestring (W) version, it is 2023:-)尝试将TestSignString
更改为 UTF-16 字符串,或引入宽字符串 (W) 版本,它是 2023:-)
function TestSignStringW(s, Sign: PWideChar): LongBool; stdcall;
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.