fix: Fix TTS COM exception in IL2CPP
This commit is contained in:
@@ -0,0 +1,102 @@
|
||||
using System;
|
||||
using System.Collections;
|
||||
using System.Runtime.CompilerServices;
|
||||
using System.Runtime.InteropServices;
|
||||
|
||||
namespace SpeechLib {
|
||||
/// <summary>Marshals the COM <see langword="IEnumVARIANT" /> interface to the .NET Framework <see cref="T:System.Collections.IEnumerator" /> interface, and vice versa.</summary>
|
||||
public class EnumeratorToEnumVariantMarshaler : ICustomMarshaler {
|
||||
[ComImport]
|
||||
[Guid("00020404-0000-0000-C000-000000000046")]
|
||||
[InterfaceType(ComInterfaceType.InterfaceIsIUnknown)]
|
||||
private interface IEnumVARIANT {
|
||||
[MethodImpl(MethodImplOptions.InternalCall, MethodCodeType = MethodCodeType.Runtime)]
|
||||
void Next(int celt, [MarshalAs(UnmanagedType.Struct)] out object rgvar, out uint pceltFetched);
|
||||
|
||||
[MethodImpl(MethodImplOptions.InternalCall, MethodCodeType = MethodCodeType.Runtime)]
|
||||
void Skip(uint celt);
|
||||
|
||||
[MethodImpl(MethodImplOptions.InternalCall, MethodCodeType = MethodCodeType.Runtime)]
|
||||
void Reset();
|
||||
|
||||
[MethodImpl(MethodImplOptions.InternalCall, MethodCodeType = MethodCodeType.Runtime)]
|
||||
[return: MarshalAs(UnmanagedType.Interface)]
|
||||
IEnumVARIANT Clone();
|
||||
}
|
||||
|
||||
private class VARIANTEnumerator : IEnumerator {
|
||||
private IEnumVARIANT com_enum;
|
||||
|
||||
private object current;
|
||||
|
||||
public object Current => current;
|
||||
|
||||
public VARIANTEnumerator(IEnumVARIANT com_enum) {
|
||||
this.com_enum = com_enum;
|
||||
}
|
||||
|
||||
public bool MoveNext() {
|
||||
uint pceltFetched = 0u;
|
||||
com_enum.Next(1, out var rgvar, out pceltFetched);
|
||||
if (pceltFetched == 0) {
|
||||
return false;
|
||||
}
|
||||
current = rgvar;
|
||||
return true;
|
||||
}
|
||||
|
||||
public void Reset() {
|
||||
com_enum.Reset();
|
||||
}
|
||||
}
|
||||
|
||||
private static EnumeratorToEnumVariantMarshaler instance;
|
||||
|
||||
/// <summary>Performs necessary cleanup of the managed data when it is no longer needed.</summary>
|
||||
/// <param name="pManagedObj">The managed object to be destroyed.</param>
|
||||
public void CleanUpManagedData(object pManagedObj) {
|
||||
throw new NotImplementedException();
|
||||
}
|
||||
|
||||
/// <summary>Performs necessary cleanup of the unmanaged data when it is no longer needed.</summary>
|
||||
/// <param name="pNativeData">A pointer to the unmanaged data to be destroyed.</param>
|
||||
public void CleanUpNativeData(IntPtr pNativeData) {
|
||||
Marshal.Release(pNativeData);
|
||||
}
|
||||
|
||||
/// <summary>Returns an instance of the custom marshaler.</summary>
|
||||
/// <param name="pstrCookie">String "cookie" parameter that can be used by the custom marshaler.</param>
|
||||
/// <returns>An instance of the custom marshaler.</returns>
|
||||
public static ICustomMarshaler GetInstance(string pstrCookie) {
|
||||
if (instance == null) {
|
||||
instance = new EnumeratorToEnumVariantMarshaler();
|
||||
}
|
||||
return instance;
|
||||
}
|
||||
|
||||
/// <summary>Returns the size in bytes of the unmanaged data to be marshaled.</summary>
|
||||
/// <returns>-1 to indicate the type this marshaler handles is not a value type.</returns>
|
||||
public int GetNativeDataSize() {
|
||||
throw new NotImplementedException();
|
||||
}
|
||||
|
||||
/// <summary>Marshals an object from managed code to unmanaged code.</summary>
|
||||
/// <param name="pManagedObj">The managed object to be converted.</param>
|
||||
/// <returns>A pointer to the unmanaged object.</returns>
|
||||
/// <exception cref="T:System.ArgumentNullException">
|
||||
/// <paramref name="pManagedObj" /> is <see langword="null" />.</exception>
|
||||
public IntPtr MarshalManagedToNative(object pManagedObj) {
|
||||
throw new NotImplementedException();
|
||||
}
|
||||
|
||||
/// <summary>Marshals an object from unmanaged code to managed code.</summary>
|
||||
/// <param name="pNativeData">A pointer to the unmanaged object to be converted.</param>
|
||||
/// <returns>A managed object.</returns>
|
||||
/// <exception cref="T:System.ArgumentNullException">
|
||||
/// <paramref name="pNativeData" /> is <see langword="null" />.</exception>
|
||||
/// <exception cref="T:System.InvalidCastException">The unmanaged object that <paramref name="pNativeData" /> points to could not be converted.</exception>
|
||||
public object MarshalNativeToManaged(IntPtr pNativeData) {
|
||||
return new VARIANTEnumerator((IEnumVARIANT)Marshal.GetObjectForIUnknown(pNativeData));
|
||||
}
|
||||
}
|
||||
}
|
Reference in New Issue
Block a user