private unsafe static int TryExcelImpl4(int xlFunction, out object result, params object[] parameters) { int xlReturn; // Set up the memory to hold the result from the call XlOper resultOper = new XlOper(); resultOper.xlType = XlType.XlTypeEmpty; XlOper *pResultOper = &resultOper; // No need to pin for local struct // Special kind of ObjectArrayMarshaler for the parameters (rank 1) using (XlObjectArrayMarshaler paramMarshaler = new XlObjectArrayMarshaler(1, true)) { XlOper **ppOperParameters = (XlOper **)paramMarshaler.MarshalManagedToNative(parameters); xlReturn = Excel4v(xlFunction, pResultOper, parameters.Length, ppOperParameters); } // pResultOper now holds the result of the evaluated function // Get ObjectMarshaler for the return value ICustomMarshaler m = XlObjectMarshaler.GetInstance(""); result = m.MarshalNativeToManaged((IntPtr)pResultOper); // And free any memory allocated by Excel Excel4v(xlFree, (XlOper *)IntPtr.Zero, 1, &pResultOper); return(xlReturn); }
internal static void XlAutoFree(IntPtr pXloper) { // CONSIDER: This might be improved.... // Another option would be to have the Com memory allocator run in unmanaged code. // Right now I think this is OK, and easiest from where I'm coming. // This function can only be called after a return from a user function. // I just free all the possibly big memory allocations. XlObjectArrayMarshaler.FreeMemory(); }