private sqlite3_context get_context(IntPtr context, IntPtr agg_context) { // agg_context is a pointer to 8 bytes of storage, obtained from // sqlite3_aggregate_context(). we will use it to store the // sqlite3_context object so we can use the same object for all // calls to xStep and xFinal for this instance/invocation of the // aggregate function. agg_sqlite3_context ctx; IntPtr c = Marshal.ReadIntPtr(agg_context); if (c == IntPtr.Zero) { // this is the first call to xStep or xFinal. we need a new // sqlite3_context object to pass to the user's callback. ctx = new agg_sqlite3_context(_user_data); // and store a handle in the agg_context storage area so we // can get this back next time. GCHandle h = GCHandle.Alloc(ctx); Marshal.WriteIntPtr(agg_context, (IntPtr)h); } else { // we've been through here before. retrieve the sqlite3_context // object from the agg_context storage area. GCHandle h = (GCHandle)c; ctx = h.Target as agg_sqlite3_context; } // we are reusing the same sqlite3_context object for each call // to xStep/xFinal within the same instance/invocation of the // user's agg function. but SQLite actually gives us a different // context pointer on each call. so we need to fix it up. ctx.fix_ptr(context); return(ctx); }
private sqlite3_context get_context(IntPtr context, IntPtr agg_context) { // agg_context is a pointer to 8 bytes of storage, obtained from // sqlite3_aggregate_context(). we will use it to store the // sqlite3_context object so we can use the same object for all // calls to xStep and xFinal for this instance/invocation of the // aggregate function. agg_sqlite3_context ctx; IntPtr c = Marshal.ReadIntPtr(agg_context); if (c == IntPtr.Zero) { // this is the first call to xStep or xFinal. we need a new // sqlite3_context object to pass to the user's callback. ctx = new agg_sqlite3_context(_user_data); // and store a handle in the agg_context storage area so we // can get this back next time. GCHandle h = GCHandle.Alloc(ctx); Marshal.WriteIntPtr(agg_context, (IntPtr) h); } else { // we've been through here before. retrieve the sqlite3_context // object from the agg_context storage area. GCHandle h = (GCHandle) c; ctx = h.Target as agg_sqlite3_context; } // we are reusing the same sqlite3_context object for each call // to xStep/xFinal within the same instance/invocation of the // user's agg function. but SQLite actually gives us a different // context pointer on each call. so we need to fix it up. ctx.fix_ptr(context); return ctx; }