mirror of
https://github.com/EasyTier/EasyTier.git
synced 2025-10-02 07:22:23 +08:00

Some checks are pending
EasyTier Core / pre_job (push) Waiting to run
EasyTier Core / build_web (push) Blocked by required conditions
EasyTier Core / build (freebsd-13.2-x86_64, 13.2, ubuntu-22.04, x86_64-unknown-freebsd) (push) Blocked by required conditions
EasyTier Core / build (linux-aarch64, ubuntu-22.04, aarch64-unknown-linux-musl) (push) Blocked by required conditions
EasyTier Core / build (linux-arm, ubuntu-22.04, arm-unknown-linux-musleabi) (push) Blocked by required conditions
EasyTier Core / build (linux-armhf, ubuntu-22.04, arm-unknown-linux-musleabihf) (push) Blocked by required conditions
EasyTier Core / build (linux-armv7, ubuntu-22.04, armv7-unknown-linux-musleabi) (push) Blocked by required conditions
EasyTier Core / build (linux-armv7hf, ubuntu-22.04, armv7-unknown-linux-musleabihf) (push) Blocked by required conditions
EasyTier Core / build (linux-mips, ubuntu-22.04, mips-unknown-linux-musl) (push) Blocked by required conditions
EasyTier Core / build (linux-mipsel, ubuntu-22.04, mipsel-unknown-linux-musl) (push) Blocked by required conditions
EasyTier Core / build (linux-x86_64, ubuntu-22.04, x86_64-unknown-linux-musl) (push) Blocked by required conditions
EasyTier Core / build (macos-aarch64, macos-latest, aarch64-apple-darwin) (push) Blocked by required conditions
EasyTier Core / build (macos-x86_64, macos-latest, x86_64-apple-darwin) (push) Blocked by required conditions
EasyTier Core / build (windows-arm64, windows-latest, aarch64-pc-windows-msvc) (push) Blocked by required conditions
EasyTier Core / build (windows-x86_64, windows-latest, x86_64-pc-windows-msvc) (push) Blocked by required conditions
EasyTier Core / core-result (push) Blocked by required conditions
EasyTier GUI / pre_job (push) Waiting to run
EasyTier GUI / build-gui (linux-aarch64, aarch64-unknown-linux-gnu, ubuntu-22.04, aarch64-unknown-linux-musl) (push) Blocked by required conditions
EasyTier GUI / build-gui (linux-x86_64, x86_64-unknown-linux-gnu, ubuntu-22.04, x86_64-unknown-linux-musl) (push) Blocked by required conditions
EasyTier GUI / build-gui (macos-aarch64, aarch64-apple-darwin, macos-latest, aarch64-apple-darwin) (push) Blocked by required conditions
EasyTier GUI / build-gui (macos-x86_64, x86_64-apple-darwin, macos-latest, x86_64-apple-darwin) (push) Blocked by required conditions
EasyTier GUI / build-gui (windows-arm64, aarch64-pc-windows-msvc, windows-latest, aarch64-pc-windows-msvc) (push) Blocked by required conditions
EasyTier GUI / build-gui (windows-x86_64, x86_64-pc-windows-msvc, windows-latest, x86_64-pc-windows-msvc) (push) Blocked by required conditions
EasyTier GUI / gui-result (push) Blocked by required conditions
EasyTier Mobile / pre_job (push) Waiting to run
EasyTier Mobile / build-mobile (android, ubuntu-22.04, android) (push) Blocked by required conditions
EasyTier Mobile / mobile-result (push) Blocked by required conditions
EasyTier Test / pre_job (push) Waiting to run
EasyTier Test / test (push) Blocked by required conditions
160 lines
4.9 KiB
C#
160 lines
4.9 KiB
C#
public class EasyTierFFI
|
|
{
|
|
// 导入 DLL 函数
|
|
private const string DllName = "easytier_ffi.dll";
|
|
|
|
[DllImport(DllName, CallingConvention = CallingConvention.Cdecl)]
|
|
private static extern int parse_config([MarshalAs(UnmanagedType.LPStr)] string cfgStr);
|
|
|
|
[DllImport(DllName, CallingConvention = CallingConvention.Cdecl)]
|
|
private static extern int run_network_instance([MarshalAs(UnmanagedType.LPStr)] string cfgStr);
|
|
|
|
[DllImport(DllName, CallingConvention = CallingConvention.Cdecl)]
|
|
private static extern int retain_network_instance(IntPtr instNames, int length);
|
|
|
|
[DllImport(DllName, CallingConvention = CallingConvention.Cdecl)]
|
|
private static extern int collect_network_infos(IntPtr infos, int maxLength);
|
|
|
|
[DllImport(DllName, CallingConvention = CallingConvention.Cdecl)]
|
|
private static extern void get_error_msg(out IntPtr errorMsg);
|
|
|
|
[DllImport(DllName, CallingConvention = CallingConvention.Cdecl)]
|
|
private static extern void free_string(IntPtr str);
|
|
|
|
// 定义 KeyValuePair 结构体
|
|
[StructLayout(LayoutKind.Sequential)]
|
|
public struct KeyValuePair
|
|
{
|
|
public IntPtr Key;
|
|
public IntPtr Value;
|
|
}
|
|
|
|
// 解析配置
|
|
public static void ParseConfig(string config)
|
|
{
|
|
if (string.IsNullOrEmpty(config))
|
|
{
|
|
throw new ArgumentException("Configuration string cannot be null or empty.");
|
|
}
|
|
|
|
int result = parse_config(config);
|
|
if (result < 0)
|
|
{
|
|
throw new Exception(GetErrorMessage());
|
|
}
|
|
}
|
|
|
|
// 启动网络实例
|
|
public static void RunNetworkInstance(string config)
|
|
{
|
|
if (string.IsNullOrEmpty(config))
|
|
{
|
|
throw new ArgumentException("Configuration string cannot be null or empty.");
|
|
}
|
|
|
|
int result = run_network_instance(config);
|
|
if (result < 0)
|
|
{
|
|
throw new Exception(GetErrorMessage());
|
|
}
|
|
}
|
|
|
|
// 保留网络实例
|
|
public static void RetainNetworkInstances(string[] instanceNames)
|
|
{
|
|
IntPtr[] namePointers = null;
|
|
IntPtr namesPtr = IntPtr.Zero;
|
|
|
|
try
|
|
{
|
|
if (instanceNames != null && instanceNames.Length > 0)
|
|
{
|
|
namePointers = new IntPtr[instanceNames.Length];
|
|
for (int i = 0; i < instanceNames.Length; i++)
|
|
{
|
|
if (string.IsNullOrEmpty(instanceNames[i]))
|
|
{
|
|
throw new ArgumentException("Instance name cannot be null or empty.");
|
|
}
|
|
namePointers[i] = Marshal.StringToHGlobalAnsi(instanceNames[i]);
|
|
}
|
|
|
|
namesPtr = Marshal.AllocHGlobal(Marshal.SizeOf<IntPtr>() * namePointers.Length);
|
|
Marshal.Copy(namePointers, 0, namesPtr, namePointers.Length);
|
|
}
|
|
|
|
int result = retain_network_instance(namesPtr, instanceNames?.Length ?? 0);
|
|
if (result < 0)
|
|
{
|
|
throw new Exception(GetErrorMessage());
|
|
}
|
|
}
|
|
finally
|
|
{
|
|
if (namePointers != null)
|
|
{
|
|
foreach (var ptr in namePointers)
|
|
{
|
|
if (ptr != IntPtr.Zero)
|
|
{
|
|
Marshal.FreeHGlobal(ptr);
|
|
}
|
|
}
|
|
}
|
|
|
|
if (namesPtr != IntPtr.Zero)
|
|
{
|
|
Marshal.FreeHGlobal(namesPtr);
|
|
}
|
|
}
|
|
}
|
|
|
|
// 收集网络信息
|
|
public static KeyValuePair<string, string>[] CollectNetworkInfos(int maxLength)
|
|
{
|
|
IntPtr buffer = Marshal.AllocHGlobal(Marshal.SizeOf<KeyValuePair>() * maxLength);
|
|
try
|
|
{
|
|
int count = collect_network_infos(buffer, maxLength);
|
|
if (count < 0)
|
|
{
|
|
throw new Exception(GetErrorMessage());
|
|
}
|
|
|
|
var result = new KeyValuePair<string, string>[count];
|
|
for (int i = 0; i < count; i++)
|
|
{
|
|
var kv = Marshal.PtrToStructure<KeyValuePair>(buffer + i * Marshal.SizeOf<KeyValuePair>());
|
|
string key = Marshal.PtrToStringAnsi(kv.Key);
|
|
string value = Marshal.PtrToStringAnsi(kv.Value);
|
|
|
|
// 释放由 FFI 分配的字符串内存
|
|
free_string(kv.Key);
|
|
free_string(kv.Value);
|
|
|
|
result[i] = new KeyValuePair<string, string>(key, value);
|
|
}
|
|
|
|
return result;
|
|
}
|
|
finally
|
|
{
|
|
Marshal.FreeHGlobal(buffer);
|
|
}
|
|
}
|
|
|
|
// 获取错误信息
|
|
private static string GetErrorMessage()
|
|
{
|
|
get_error_msg(out IntPtr errorMsgPtr);
|
|
if (errorMsgPtr == IntPtr.Zero)
|
|
{
|
|
return "Unknown error";
|
|
}
|
|
|
|
string errorMsg = Marshal.PtrToStringAnsi(errorMsgPtr);
|
|
free_string(errorMsgPtr); // 释放错误信息字符串
|
|
return errorMsg;
|
|
}
|
|
}
|