由于编码,在iOS上从C#调用DLL库时出现问题

时间:2013-05-16 12:17:44

标签: c# dll character-encoding xamarin.ios dllimport

我有特殊问题。我使用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中的二进制块(预编译块)调用这个函数。比buff更像是一个字节数组。

现在我的问题是,字符串工作完美。但二进制块转换错误。我不得不将字节数组转换为字符串,该字符串采用UTF-16进行C#编码。如果我调用该函数,则此“字符串”将从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不起作用。

1 个答案:

答案 0 :(得分:2)

使用.NET,您可以创建指向相同原生的两个托管方法(通过更改DllImport属性属性重载或使用不同的名称)功能

第一个将使用string参数。这就是你已经拥有的。

第二个将使用byte[]参数。这将确保在转到本机之前不对数据进行解码(和修改)。类似的东西:

[DllImport(LIBNAME,CallingConvention=CallingConvention.Cdecl)]
public static extern int luaL_loadbuffer(IntPtr luaState, 
                                     byte[] buff, 
                                     uint size, 
                                     string name);