/// <summary> /// Calls the native V8 proxy library to create a JavaScript array for use within the V8 JavaScript environment. /// </summary> public InternalHandle CreateArray(params InternalHandle[] items) { HandleProxy **nativeArrayMem = items.Length > 0 ? Utilities.MakeHandleProxyArray(items) : null; InternalHandle handle = V8NetProxy.CreateArray(_NativeV8EngineProxy, nativeArrayMem, items.Length); Utilities.FreeNativeMemory((IntPtr)nativeArrayMem); return(handle); }
/// <summary> /// Calls the native V8 proxy library to create the value instance for use within the V8 JavaScript environment. /// <para>This overload provides a *quick way* to construct an array of strings. /// One big memory block is created to marshal the given strings at one time, which is many times faster than having to create an array of individual native strings.</para> /// </summary> public InternalHandle CreateValue(IEnumerable <string> items) { if (items == null) { return(V8NetProxy.CreateArray(_NativeV8EngineProxy, null, 0)); } var itemsEnum = items.GetEnumerator(); int strBufSize = 0; // (size needed for the string chars portion of the memory block) int itemsCount = 0; while (itemsEnum.MoveNext()) { // get length of all strings together strBufSize += itemsEnum.Current.Length + 1; // (+1 for null char) itemsCount++; } itemsEnum.Reset(); int strPtrBufSize = Marshal.SizeOf(typeof(IntPtr)) * itemsCount; // start buffer size with size needed for all string pointers. char **oneBigStringBlock = (char **)Utilities.AllocNativeMemory(strPtrBufSize + Marshal.SystemDefaultCharSize * strBufSize); char **ptrWritePtr = oneBigStringBlock; char * strWritePtr = (char *)(((byte *)oneBigStringBlock) + strPtrBufSize); int itemLength; while (itemsEnum.MoveNext()) { itemLength = itemsEnum.Current.Length; Marshal.Copy(itemsEnum.Current.ToCharArray(), 0, (IntPtr)strWritePtr, itemLength); Marshal.WriteInt16((IntPtr)(strWritePtr + itemLength), 0); Marshal.WriteIntPtr((IntPtr)ptrWritePtr++, (IntPtr)strWritePtr); strWritePtr += itemLength + 1; } InternalHandle handle = V8NetProxy.CreateStringArray(_NativeV8EngineProxy, oneBigStringBlock, itemsCount); Utilities.FreeNativeMemory((IntPtr)oneBigStringBlock); return(handle); }
// -------------------------------------------------------------------------------------------------------------------- /// <summary> /// Calls the underlying native function to create and return a new instance, which will be wrapped in the specified managed object type. /// </summary> /// <typeparam name="T">A managed object type to wrap the new native object handle.</typeparam> /// <param name="args">Arguments to pass to the function to construct the new native instance.</param> /// <returns>A new instance of 'T'.</returns> public V8ManagedObject CreateInstance <T>(params InternalHandle[] args) // TODO: Parameter passing needs testing. where T : V8ManagedObject, new() { HandleProxy **_args = null; if (args.Length > 0) { _args = (HandleProxy **)Utilities.AllocPointerArray(args.Length); for (var i = 0; i < args.Length; i++) { _args[i] = args[i]; } } // (note: the special case here is that the native function object will use its own template to create instances) T obj = _Engine._CreateManagedObject <T>(this, null); obj.Template = InstanceTemplate; try { obj._Handle.Set(V8NetProxy.CreateInstanceFromFunctionTemplate(_NativeFunctionTemplateProxy, obj.ID, args.Length, _args)); // (note: setting '_NativeObject' also updates it's '_ManagedObject' field if necessary. obj.Initialize(true, args); } catch (Exception ex) { // ... something went wrong, so remove the new managed object ... _Engine._RemoveObjectWeakReference(obj.ID); throw ex; } finally { Utilities.FreeNativeMemory((IntPtr)_args); } return(obj); }
// -------------------------------------------------------------------------------------------------------------------- /// <summary> /// Calls the underlying native function to create a new native object and return its handle. /// Use this method if you only need the native object and not a managed wrapper. /// </summary> /// <param name="args">Arguments to pass to the function to construct the new native instance.</param> /// <returns>A handle to the new object.</returns> public InternalHandle CreateNativeInstance(params InternalHandle[] args) // TODO: Parameter passing needs testing. { HandleProxy **_args = null; if (args.Length > 0) { _args = (HandleProxy **)Utilities.AllocPointerArray(args.Length); for (var i = 0; i < args.Length; i++) { _args[i] = args[i]; } } try { return((InternalHandle)V8NetProxy.CreateInstanceFromFunctionTemplate(_NativeFunctionTemplateProxy, -1, args.Length, _args)); } finally { Utilities.FreeNativeMemory((IntPtr)_args); } }