难点主要是复杂数据类型的映射,包括字符串数组和自定义结构,一般方法是使用约定好的连续内存的二进制流的格式,先从C库中创建连续内存,C#中使用Marshal.Copy到本地的byte[],然后在本地对二进制流进行分割,依次将各个字段填入本地的离散的变量中。这种方式由于增加了两次内存的拷贝,因此效率会损失一些。
下面是一个例子
using System.Runtime.InteropServices;
[DllImport(ClientDLL, EntryPoint = "Redis_del", CharSet = CharSet.Ansi, CallingConvention = CallingConvention.Cdecl)]
private static extern int Redis_del(
[In, MarshalAs(UnmanagedType.SysUInt)] IntPtr rediskey,
[In, MarshalAs(UnmanagedType.LPStr)] string key
);
[DllImport(ClientDLL, EntryPoint = "Redis_exists", CharSet = CharSet.Ansi, CallingConvention = CallingConvention.Cdecl)]
private static extern bool Redis_exists(
[In, MarshalAs(UnmanagedType.SysUInt)] IntPtr rediskey,
[In, MarshalAs(UnmanagedType.LPStr)] string key
);
[DllImport(ClientDLL, EntryPoint = "Redis_expire", CharSet = CharSet.Ansi, CallingConvention = CallingConvention.Cdecl)]
private static extern int Redis_expire(
[In, MarshalAs(UnmanagedType.SysUInt)] IntPtr rediskey,
[In, MarshalAs(UnmanagedType.LPStr)] string key,
[In, MarshalAs(UnmanagedType.I4)] int seconds
);
[DllImport(ClientDLL, EntryPoint = "Redis_pexpire", CharSet = CharSet.Ansi, CallingConvention = CallingConvention.Cdecl)]
private static extern int Redis_pexpire(
[In, MarshalAs(UnmanagedType.SysUInt)] IntPtr rediskey,
[In, MarshalAs(UnmanagedType.LPStr)] string key,
[In, MarshalAs(UnmanagedType.U4)] int milliseconds
);
[DllImport(ClientDLL, EntryPoint = "Redis_expireat", CharSet = CharSet.Ansi, CallingConvention = CallingConvention.Cdecl)]
private static extern int Redis_expireat(
[In, MarshalAs(UnmanagedType.SysUInt)] IntPtr rediskey,
[In, MarshalAs(UnmanagedType.LPStr)] string key,
[In, MarshalAs(UnmanagedType.I8)] Int64 stamp
);
[DllImport(ClientDLL, EntryPoint = "Redis_keys_pattern", CharSet = CharSet.Ansi, CallingConvention = CallingConvention.Cdecl)]
private static extern int Redis_keys_pattern(
[In, MarshalAs(UnmanagedType.SysUInt)] IntPtr rediskey,
[In, MarshalAs(UnmanagedType.LPStr)] string pattern,
[In,Out, MarshalAs(UnmanagedType.SysUInt)] ref IntPtr keys,
[In,Out, MarshalAs(UnmanagedType.I4)] ref int datalen,
[In,Out, MarshalAs(UnmanagedType.I4)] ref int count
);
[DllImport(ClientDLL, EntryPoint = "Redis_randomkey", CharSet = CharSet.Ansi, CallingConvention = CallingConvention.Cdecl)]
private static extern bool Redis_randomkey(
[In, MarshalAs(UnmanagedType.SysUInt)] IntPtr rediskey,
[In,Out, MarshalAs(UnmanagedType.SysUInt)] ref IntPtr buf,
[In,Out, MarshalAs(UnmanagedType.I4)] ref int buflen
);
[DllImport(ClientDLL, EntryPoint = "Redis_rename_key", CharSet = CharSet.Ansi, CallingConvention = CallingConvention.Cdecl)]
private static extern bool Redis_rename_key(
[In, MarshalAs(UnmanagedType.SysUInt)] IntPtr rediskey,
[In, MarshalAs(UnmanagedType.LPStr)] string key,
[In, MarshalAs(UnmanagedType.LPStr)] string newkey
);
[DllImport(ClientDLL, EntryPoint = "Redis_renamenx", CharSet = CharSet.Ansi, CallingConvention = CallingConvention.Cdecl)]
private static extern bool Redis_renamenx(
[In, MarshalAs(UnmanagedType.SysUInt)] IntPtr rediskey,
[In, MarshalAs(UnmanagedType.LPStr)] string key,
[In, MarshalAs(UnmanagedType.LPStr)] string newkey
);
[DllImport(ClientDLL, EntryPoint = "Redis_ttl", CharSet = CharSet.Ansi, CallingConvention = CallingConvention.Cdecl)]
private static extern int Redis_ttl(
[In, MarshalAs(UnmanagedType.SysUInt)] IntPtr rediskey,
[In, MarshalAs(UnmanagedType.LPStr)] string key
);
[DllImport(ClientDLL, EntryPoint = "Redis_pttl", CharSet = CharSet.Ansi, CallingConvention = CallingConvention.Cdecl)]
private static extern Int64 Redis_pttl(
[In, MarshalAs(UnmanagedType.SysUInt)] IntPtr rediskey,
[In, MarshalAs(UnmanagedType.LPStr)] string key
);
[DllImport(ClientDLL, EntryPoint = "Redis_type", CharSet = CharSet.Ansi, CallingConvention = CallingConvention.Cdecl)]
private static extern int Redis_type(
[In, MarshalAs(UnmanagedType.SysUInt)] IntPtr rediskey,
[In, MarshalAs(UnmanagedType.LPStr)] string key
);