我有一个特殊的问题。我使用 Xamarin.iOS 并尝试调用 DLL 库的函数。原函数定义为
LUALIB_API int luaL_loadbuffer (lua_State *L,
const char *buff,
size_t size,
const char *name)
并在 C# 中导入为
[CLSCompliant (false)]
[DllImport(LIBNAME,CallingConvention=CallingConvention.Cdecl)]
public static extern int luaL_loadbuffer(IntPtr luaState,
string buff,
uint size,
string name);
如果您可以看到,该库是 Lua 5.1,C# 端是 KeraLua,它是该库的包装器。从 Lua 中,您可以使用 buff 中的字符串调用此函数,例如“a=2”,然后将其编译为 Lua 的二进制代码。但您也可以使用 buff 中的二进制 block (预编译 block )来调用此函数。比buff是一个字节数组。
现在我的问题是,字符串工作完美。但二进制 block 转换错误。我必须将字节数组转换为字符串,该字符串在 C# 中以 UTF-16 编码。如果我调用该函数,该“字符串”将从 UTF-16 转换为 UTF-8。这没问题,当 buff 包含文本时,但包含二进制数据时,结果是错误的。
示例:二进制数据中的整数,在字节数组中看起来为 D6 21 00 00,转换为字符串
StringBuilder s = new StringBuilder();
foreach (byte b in byteArray)
s.Append((char)b);
结果是D6 21 00 00。然后调用该函数并在库中得到C3 96 21 00 00,这显然是错误的。这是因为 UTF-16 D6 是 UTF-8 C3 96,并且在调用该函数时发生了更改。
最后,我应该如何定义/调用该函数,以便不发生这种转换?使用 Encoding.Ansi 或 Encoding.ASCII 不起作用。
最佳答案
使用 .NET,您可以创建指向相同 native 函数的两个托管方法(通过更改 DllImport
属性来重载或使用不同的名称)。
第一个将使用 string
范围。这就是您已经拥有的。
第二个将使用 byte[]
范围。这将确保数据在进入 native 之前不会被解码(和修改)。像这样的东西:
[DllImport(LIBNAME,CallingConvention=CallingConvention.Cdecl)]
public static extern int luaL_loadbuffer(IntPtr luaState,
byte[] buff,
uint size,
string name);
关于c# - 由于编码问题,在 iOS 上从 C# 调用 DLL 库时出现问题,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/16587230/