using System; using System.Runtime.InteropServices; using System.Text; namespace CloudPointRpc { public static partial class CrpcTestApi { private const string DllName = "test_cloud_point"; [UnmanagedFunctionPointer(CallingConvention.Cdecl)] public delegate IntPtr RpcStringCallback(IntPtr rpcString); [DllImport(DllName, CallingConvention = CallingConvention.Cdecl)] public static extern void crpc_test_init(); [DllImport(DllName, CallingConvention = CallingConvention.Cdecl)] public static extern void crpc_test_deinit(); [DllImport(DllName, CallingConvention = CallingConvention.Cdecl)] public static extern void crpc_test_add_method(RpcStringCallback cb, IntPtr name); [DllImport(DllName, CallingConvention = CallingConvention.Cdecl)] public static extern int crpc_test_remove_method(IntPtr name); [DllImport(DllName, CallingConvention = CallingConvention.Cdecl)] public static extern void crpc_test_schedule_call(IntPtr name); [DllImport(DllName, CallingConvention = CallingConvention.Cdecl)] public static extern void crpc_test_change_duration(ulong durationMs); [DllImport(DllName, CallingConvention = CallingConvention.Cdecl)] public static extern ulong crpc_test_duration(); [DllImport(DllName, CallingConvention = CallingConvention.Cdecl)] public static extern void crpc_test_auto_call(uint state); } public static partial class CrpcServerApi { private const string DllName = "libcloud_point_rpc"; [DllImport(DllName, CallingConvention = CallingConvention.Cdecl, CharSet = CharSet.Ansi)] public static extern IntPtr crpc_str_get_data(IntPtr rpcString); [DllImport(DllName, CallingConvention = CallingConvention.Cdecl)] public static extern ulong crpc_str_get_size(IntPtr rpcString); [DllImport(DllName, CallingConvention = CallingConvention.Cdecl, CharSet = CharSet.Ansi)] public static extern IntPtr crpc_str_create(byte[] data, ulong size); [DllImport(DllName, CallingConvention = CallingConvention.Cdecl)] public static extern void crpc_str_destroy(IntPtr rpcString); [DllImport(DllName, CallingConvention = CallingConvention.Cdecl, CharSet = CharSet.Ansi)] public static extern void crpc_init(byte[] configPath); [DllImport(DllName, CallingConvention = CallingConvention.Cdecl)] public static extern void crpc_deinit(); [DllImport(DllName, CallingConvention = CallingConvention.Cdecl)] public static extern void crpc_add_method(CrpcTestApi.RpcStringCallback cb, IntPtr name); } public sealed class RpcString : IDisposable { private IntPtr _handle; private bool _disposed; public IntPtr Handle => _handle; public RpcString(string data) { var bytes = Encoding.ASCII.GetBytes(data); _handle = CrpcServerApi.crpc_str_create(bytes, (ulong)bytes.Length); } internal RpcString(IntPtr handle) { _handle = handle; } public string Data { get { if (_disposed || _handle == IntPtr.Zero) return string.Empty; var dataPtr = CrpcServerApi.crpc_str_get_data(_handle); var size = CrpcServerApi.crpc_str_get_size(_handle); if (dataPtr == IntPtr.Zero || size == 0) return string.Empty; return Marshal.PtrToStringAnsi(dataPtr, (int)size) ?? string.Empty; } } public void Dispose() { if (!_disposed && _handle != IntPtr.Zero) { CrpcServerApi.crpc_str_destroy(_handle); _handle = IntPtr.Zero; _disposed = true; } } ~RpcString() { Dispose(); } } public static class CrpcExtensions { public static string CrpcStrGetData(IntPtr rpcString) { var dataPtr = CrpcServerApi.crpc_str_get_data(rpcString); var size = CrpcServerApi.crpc_str_get_size(rpcString); if (dataPtr == IntPtr.Zero || size == 0) return string.Empty; return Marshal.PtrToStringAnsi(dataPtr, (int)size) ?? string.Empty; } public static ulong CrpcStrGetSize(IntPtr rpcString) { return CrpcServerApi.crpc_str_get_size(rpcString); } public static IntPtr CrpcStrCreate(string data) { var bytes = Encoding.UTF8.GetBytes(data); return CrpcServerApi.crpc_str_create(bytes, (ulong)bytes.Length); } public static void CrpcStrDestroy(IntPtr rpcString) { CrpcServerApi.crpc_str_destroy(rpcString); } public static void CrpcInit(string configPath) { var bytes = Encoding.UTF8.GetBytes(configPath + '\0'); CrpcServerApi.crpc_init(bytes); } public static void CrpcDeinit() { CrpcServerApi.crpc_deinit(); } public static void CrpcAddMethod(CrpcTestApi.RpcStringCallback cb, string name) { using var nameRpc = new RpcString(name); CrpcServerApi.crpc_add_method(cb, nameRpc.Handle); } } public static class CrpcTestExtensions { public static void CrpcTestAddMethod(CrpcTestApi.RpcStringCallback cb, string name) { using var nameRpc = new RpcString(name); CrpcTestApi.crpc_test_add_method(cb, nameRpc.Handle); } public static int CrpcTestRemoveMethod(string name) { using var nameRpc = new RpcString(name); return CrpcTestApi.crpc_test_remove_method(nameRpc.Handle); } public static void CrpcTestScheduleCall(string name) { using var nameRpc = new RpcString(name); CrpcTestApi.crpc_test_schedule_call(nameRpc.Handle); } public static void CrpcAddMethod(CrpcTestApi.RpcStringCallback cb, string name) { using var nameRpc = new RpcString(name); CrpcServerApi.crpc_add_method(cb, nameRpc.Handle); } public static void CrpcInit(string configPath) { var bytes = Encoding.UTF8.GetBytes(configPath + '\0'); CrpcServerApi.crpc_init(bytes); } } }