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

yzckvree  于 2023-06-05  发布在  其他
关注(0)|答案(2)|浏览(170)

我有一个 Delphi 2007的DLL与此导出:

function TestSignString(s, Sign: PChar): LongBool; stdcall;

我在.NET Core v7 C#中使用这个导入调用它:

[DllImport(@"LibraryName.dll")]
[return:MarshalAs(UnmanagedType.Bool)]
internal static extern bool TestSignString(string s, string sign);

我正在传递ssign参数,当运行时系统具有默认编码(EXPECTED)WIN 1250时,一切都按预期进行,但是当它不是时,涉及默认系统编码,并且使用默认编码对传递的字符进行编码(例如WIN 1252)。
所以我的问题是,如何在C#中封送字符串时覆盖默认编码?我的意思是两种方式-作为一个输入参数和输出,以及,请。
我尝试将导入更改为:

[DllImport(@"LockBoxLibrary.dll", CharSet = CharSet.Ansi)]

但没有运气,我缺少代码页(1250)规范。

kmynzznz

kmynzznz1#

我有一个“肮脏”的解决方案,因为它可能是内存泄漏。如果你知道更好的方法,请告诉我。我有两个扩展方法可以将字符串转换为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();

导入更改为:private static extern bool TestSignString(nint s, nint sign);
方法调用:TestSignString(s.FromUtf8StrToAnsiPtr(), sign.FromUtf8StrToAnsiPtr());

6rvt4ljy

6rvt4ljy2#

尝试将TestSignString改为UTF-16字符串,或者引入宽字符串(W)版本,它是2023:-)

function TestSignStringW(s, Sign: PWideChar): LongBool; stdcall;

相关问题