Files
lserp_cs_5.0/插件库/Cef3.24/Structs/CefMainArgs.cs
T
2026-07-10 15:25:05 +08:00

117 lines
3.3 KiB
C#

namespace Cef3
{
using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.Text;
using System.Reflection;
using System.Runtime.InteropServices;
using Cef3.Interop;
using Windows = Cef3.Platform.Windows;
public sealed unsafe class CefMainArgs
{
private readonly string[] _args;
private IntPtr _argcArgvBlock;
public CefMainArgs(string[] args)
{
_args = args;
_argcArgvBlock = IntPtr.Zero;
}
internal cef_main_args_t* ToNative()
{
switch (CefRuntime.Platform)
{
case CefRuntimePlatform.Windows:
return (cef_main_args_t*)ToNativeWindows();
case CefRuntimePlatform.Linux:
case CefRuntimePlatform.MacOSX:
return (cef_main_args_t*)ToNativePosix();
default:
throw ExceptionBuilder.UnsupportedPlatform();
}
}
private cef_main_args_t_windows* ToNativeWindows()
{
var ptr = cef_main_args_t_windows.Alloc();
ptr->instance = Windows.NativeMethods.GetModuleHandle(null);
return ptr;
}
private cef_main_args_t_posix* ToNativePosix()
{
var ptr = cef_main_args_t_posix.Alloc();
if (_args != null)
{
ptr->argv = MarshallArgcArgvBlock(_args);
ptr->argc = _args.Length;
}
return ptr;
}
// TODO: check this, and reimplement CefMainArgs to do not leak memory
private IntPtr MarshallArgcArgvBlock(string[] args)
{
Debug.Assert(args != null);
var encoding = Encoding.UTF8;
// calculate required block length
var sizeOfArray = sizeof(IntPtr) * (args.Length + 1); // sizeof array of pointers to arguments
var size = sizeOfArray; // size for entire block
foreach (var arg in args)
{
size += 1 + encoding.GetByteCount(arg ?? "");
}
byte** argv = (byte**)Marshal.AllocHGlobal(size);
byte* data = (byte*)argv + sizeOfArray;
for (var i=0; i < args.Length; i++)
{
argv[i] = data;
var bytes = encoding.GetBytes(args[i]);
Marshal.Copy(bytes, 0, (IntPtr)data, bytes.Length);
data += bytes.Length;
data[0] = 0;
data++;
}
argv[args.Length] = (byte*)0;
return (IntPtr)argv;
}
private void FreeArgcArgvBlock(IntPtr ptr)
{
Marshal.FreeHGlobal(ptr);
}
internal static void Free(cef_main_args_t* ptr)
{
switch (CefRuntime.Platform)
{
case CefRuntimePlatform.Windows:
cef_main_args_t_windows.Free((cef_main_args_t_windows*)ptr);
return;
case CefRuntimePlatform.Linux:
case CefRuntimePlatform.MacOSX:
cef_main_args_t_posix.Free((cef_main_args_t_posix*)ptr);
return;
default:
throw ExceptionBuilder.UnsupportedPlatform();
}
}
}
}