简体   繁体   English

编组字符串时如何覆盖默认编码?

[英]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).我正在传递ssign参数,当运行时系统具有默认编码(预期)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.

相关问题 在 P/Invoke 中编组字符串时 Mono 使用什么编码? - What encoding does Mono use when marshalling strings in P/Invoke? 当焦点位于TextBox中时,如何覆盖表单上的默认按钮 - How can I override the default button on a form when focus is in a TextBox 当没有显式注入依赖项时,如何使用依赖关系注入来覆盖方法或设置默认方法? - How can I use Dependency Injection to either Override a method or to set a default method when no dependency is explicitly injected? 如何确定便携式类库中的默认编码? - How can I determine the default encoding in a portable class library? 如何更改 System.Text.Encoding.Default? - How can I change System.Text.Encoding.Default? 如何覆盖默认的未捕获异常对话框? - How can I override the default uncaught exception dialog? 如何覆盖 Identity Server 4 中的默认错误路径? - How can I override the default error path in Identity Server 4? 编组包含 ByValTStr 字符串的结构时是否需要调用 Marshal.DestroyStructure - Do I need to call Marshal.DestroyStructure when marshalling structures containing ByValTStr strings 将字符串从C ++编组到C#时会感到兴奋 - Getting an excpetion when Marshalling Strings from C++ to C# 如何覆盖默认的“全局”键盘快捷键并创建我自己的快捷键? - How can I override default “global” keyboard shortcuts and create my own instead?
 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM