117 lines
3.3 KiB
C#
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();
|
|
}
|
|
}
|
|
}
|
|
}
|