internal void SetVariantValue(int offset, object value) { IntPtr ptrZero = ADP.PtrZero; bool success = false; RuntimeHelpers.PrepareConstrainedRegions(); try { base.DangerousAddRef(ref success); ptrZero = ADP.IntPtrOffset(base.DangerousGetHandle(), offset); RuntimeHelpers.PrepareConstrainedRegions(); try { Marshal.GetNativeVariantForObject(value, ptrZero); } finally { NativeOledbWrapper.MemoryCopy(ADP.IntPtrOffset(ptrZero, ODB.SizeOf_Variant), ptrZero, ODB.SizeOf_Variant); } } finally { if (success) { base.DangerousRelease(); } } }
// translate to native internal void SetVariantValue(int offset, object value) { // two contigous VARIANT structures, second should be a binary copy of the first Debug.Assert(_needToReset, "data type requires reseting and _needToReset is false"); Debug.Assert(0 == (ODB.SizeOf_Variant % 8), "unexpected VARIANT size mutiplier"); Debug.Assert(0 == offset % 8, "invalid alignment"); ValidateCheck(offset, 2 * ODB.SizeOf_Variant); IntPtr buffer = ADP.PtrZero; bool mustRelease = false; RuntimeHelpers.PrepareConstrainedRegions(); try { DangerousAddRef(ref mustRelease); buffer = ADP.IntPtrOffset(DangerousGetHandle(), offset); RuntimeHelpers.PrepareConstrainedRegions(); try { // GetNativeVariantForObject must be in try block since it has no reliability contract Marshal.GetNativeVariantForObject(value, buffer); } finally { // safe to copy memory(dst,src,count), even if GetNativeVariantForObject failed NativeOledbWrapper.MemoryCopy(ADP.IntPtrOffset(buffer, ODB.SizeOf_Variant), buffer, ODB.SizeOf_Variant); } } finally { if (mustRelease) { DangerousRelease(); } } }