Пример #1
0
        /// <summary>
        /// Creates a new view to this texture.
        /// </summary>
        /// <param name="firstMipIndex">The index of the first mip-level in the texture that will be accessible through the returned view.</param>
        /// <param name="numMips">The number of mip-levels in this texture that will be accessible through the returned view.</param>
        /// <returns>A new resource view that permits reading data from this texture.</returns>
        public override ShaderTextureResourceView CreateView(uint firstMipIndex, uint numMips)
        {
            if (firstMipIndex + numMips > NumMips || numMips == 0U)
            {
                throw new ArgumentOutOfRangeException("numMips");
            }
            if ((PermittedBindings & GPUBindings.ReadableShaderResource) != GPUBindings.ReadableShaderResource)
            {
                throw new InvalidOperationException("Can not create an shader resource view to a resource that was created without the "
                                                    + GPUBindings.ReadableShaderResource + " binding.");
            }

            ShaderResourceViewHandle outViewHandle;

            InteropUtils.CallNative(
                NativeMethods.ResourceFactory_CreateSRVToTexture3D,
                RenderingModule.Device,
                (Texture3DResourceHandle)ResourceHandle,
                GetFormatForType(TexelFormat),
                firstMipIndex,
                numMips,
                (IntPtr)(&outViewHandle)
                ).ThrowOnFailure();

            return(new ShaderTextureResourceView(outViewHandle, this, firstMipIndex, numMips));
        }
Пример #2
0
        public void TestInteropUtilsNativeCallMethods()
        {
            // Define variables and constants
            const string EXPECTED_FAIL_REASON = "I feel sad, so left alone; words are not enough, to live on";

            // Set up context


            // Execute
            bool manualSuccessResult;

            unsafe {
                char *failReason = stackalloc char[InteropUtils.MAX_INTEROP_FAIL_REASON_STRING_LENGTH + 1];
                manualSuccessResult = ReturnSuccess((IntPtr)failReason);
            }
            bool   manualFailureResult;
            string manualFailureMessage;

            unsafe {
                char *failReason = stackalloc char[InteropUtils.MAX_INTEROP_FAIL_REASON_STRING_LENGTH + 1];
                manualFailureResult  = ReturnFailure((IntPtr)failReason, EXPECTED_FAIL_REASON);
                manualFailureMessage = Marshal.PtrToStringUni((IntPtr)failReason);
            }

            NativeCallResult successNCR = InteropUtils.CallNative(ReturnSuccess);
            NativeCallResult failureNCR = InteropUtils.CallNative(ReturnFailure, EXPECTED_FAIL_REASON);

            // Assert outcome
            Assert.AreEqual(manualSuccessResult, successNCR.Success);
            Assert.AreEqual(manualFailureResult, failureNCR.Success);
            Assert.IsNull(null, successNCR.FailureMessage);
            Assert.AreEqual(manualFailureMessage, failureNCR.FailureMessage);
        }
Пример #3
0
        /// <summary>
        /// Creates a new unordered access view to this texture.
        /// </summary>
        /// <param name="mipIndex">The mip-level to create a view to. Only one mip-level can be exposed in an <see cref="UnorderedAccessView"/>.</param>
        /// <param name="firstSliceIndex">The index of the first slice of this 3D texture to expose through the returned view.</param>
        /// <param name="numSlices">The number of slices of this 3D texture to expose through the returned view.</param>
        /// <returns>A new resource view that permits reading and writing data from/to this texture.</returns>
        public UnorderedTextureAccessView CreateUnorderedAccessView(uint mipIndex, uint firstSliceIndex, uint numSlices)
        {
            if (firstSliceIndex + numSlices > Depth || numSlices == 0U)
            {
                throw new ArgumentOutOfRangeException("numSlices");
            }
            if (mipIndex >= NumMips)
            {
                throw new ArgumentOutOfRangeException("mipIndex");
            }
            if ((PermittedBindings & GPUBindings.WritableShaderResource) != GPUBindings.WritableShaderResource)
            {
                throw new InvalidOperationException("Can not create an unordered access view to a resource that was created without the "
                                                    + GPUBindings.WritableShaderResource + " binding.");
            }

            UnorderedAccessViewHandle outViewHandle;

            InteropUtils.CallNative(
                NativeMethods.ResourceFactory_CreateUAVToTexture3D,
                RenderingModule.Device,
                (Texture3DResourceHandle)ResourceHandle,
                GetFormatForType(TexelFormat),
                mipIndex,
                firstSliceIndex,
                numSlices,
                (IntPtr)(&outViewHandle)
                ).ThrowOnFailure();

            return(new UnorderedTextureAccessView(outViewHandle, this, mipIndex));
        }
Пример #4
0
        void IDisposable.Dispose()
        {
            lock (WindowMutationLock) {
                if (isDisposed)
                {
                    return;
                }
                isDisposed = true;

                lock (staticMutationLock) {
                    openWindows.Remove(this);
                }

                LosgapSystem.InvokeOnMasterAsync(() => {
                    if (!*windowClosureFlagPtr)
                    {
                        InteropUtils.CallNative(NativeMethods.WindowFactory_CloseWindow, WindowHandle).ThrowOnFailure();
                    }
                    InteropUtils.CallNative(NativeMethods.WindowFactory_CleanUpWindowResources, WindowHandle).ThrowOnFailure();
                });

                ClearViewports().ForEach(vp => vp.Dispose());

                OnWindowClosed();
            }
        }
 internal unsafe static PhysicsBodyHandle CreateRigidBody(PhysicsShapeHandle shapeHandle, float mass, bool alwaysActive, bool forceIntransigence, bool collideOnlyAgainstWorld, bool collideAgainstDynamicsOnly, IntPtr translationPtr, IntPtr rotationPtr, IntPtr shapeOffsetPtr)
 {
     Assure.GreaterThanOrEqualTo(mass, 0f);
     if (collideOnlyAgainstWorld && collideAgainstDynamicsOnly)
     {
         throw new ArgumentException("Can't collide against world and only dynamics simultaneously.");
     }
     return(LosgapSystem.InvokeOnMaster(() => {
         PhysicsBodyHandle result;
         InteropUtils.CallNative(
             NativeMethods.PhysicsManager_CreateRigidBody,
             translationPtr,
             rotationPtr,
             shapeOffsetPtr,
             shapeHandle,
             mass,
             (InteropBool)alwaysActive,
             (InteropBool)forceIntransigence,
             (InteropBool)collideOnlyAgainstWorld,
             (InteropBool)collideAgainstDynamicsOnly,
             (IntPtr)(&result)
             ).ThrowOnFailure();
         return result;
     }));
 }
Пример #6
0
        public void TryAdd(string aLocation)
        {
            IntPtr location = InteropUtils.StringToHGlobalUtf8(aLocation);

            CpDeviceListUpnpTryAdd(iHandle, location);
            Marshal.FreeHGlobal(location);
        }
 internal static void DestroyShape(PhysicsShapeHandle shape)
 {
     LosgapSystem.InvokeOnMasterAsync(() => InteropUtils.CallNative(
                                          NativeMethods.PhysicsManager_DestroyShape,
                                          shape
                                          ).ThrowOnFailure());
 }
 internal static void DestroyConstraint(FixedConstraintHandle constraint)
 {
     LosgapSystem.InvokeOnMasterAsync(() => InteropUtils.CallNative(
                                          NativeMethods.PhysicsManager_DestroyConstraint,
                                          constraint
                                          ).ThrowOnFailure());
 }
 public static unsafe PhysicsShapeHandle CreateConcaveHullShape(IEnumerable <Vector3> vertices, IEnumerable <int> indices, CollisionShapeOptionsDesc shapeOptions, string acdFilePath)
 {
     return(LosgapSystem.InvokeOnMaster(() => {
         AlignedAllocation <CollisionShapeOptionsDesc> shapeOptionsAligned = new AlignedAllocation <CollisionShapeOptionsDesc>(16L, (uint)sizeof(CollisionShapeOptionsDesc));
         *((CollisionShapeOptionsDesc *)shapeOptionsAligned.AlignedPointer) = shapeOptions;
         Vector3 *verticesLocal = stackalloc Vector3[vertices.Count()];
         int *indicesLocal = stackalloc int[indices.Count()];
         int numVertices = 0;
         int numIndices = 0;
         foreach (Vector3 vertex in vertices)
         {
             verticesLocal[numVertices++] = vertex;
         }
         foreach (int index in indices)
         {
             indicesLocal[numIndices++] = index;
         }
         PhysicsShapeHandle result;
         InteropUtils.CallNative(
             NativeMethods.PhysicsManager_CreateConcaveHullShape,
             (IntPtr)verticesLocal,
             numVertices,
             (IntPtr)indicesLocal,
             numIndices,
             shapeOptionsAligned.AlignedPointer,
             acdFilePath,
             (IntPtr)(&result)
             ).ThrowOnFailure();
         shapeOptionsAligned.Dispose();
         return result;
     }));
 }
Пример #10
0
        /// <summary>
        /// Constructor for string input argument for an action
        /// </summary>
        /// <remarks>Intended to be write only (its value is written on construction and not be later read)</remarks>
        /// <param name="aParameter">Defines the name plus any bounds to the value for the argument.
        /// Must have been previously added to the action using Action.AddInputParameter</param>
        /// <param name="aValue">Value for the argument</param>
        public ArgumentString(ParameterString aParameter, String aValue)
        {
            IntPtr value = InteropUtils.StringToHGlobalUtf8(aValue);

            iHandle = ActionArgumentCreateStringInput(aParameter.Handle(), value);
            Marshal.FreeHGlobal(value);
        }
        /// <summary>
        /// Creates a new <see cref="IndexBuffer"/> with the supplied builder parameters.
        /// </summary>
        /// <remarks>
        /// In debug mode, this method will check a large number of <see cref="Assure">assurances</see>
        /// on the builder parameters before creating the resource.
        /// </remarks>
        /// <returns>A new <see cref="IndexBuffer"/>.</returns>
        public unsafe override IndexBuffer Create()
        {
            Assure.True(Usage != ResourceUsage.Immutable || InitialData != null, "You must supply initial data to an immutable resource.");
            Assure.GreaterThan(length, 0U, "Can not create an index buffer with 0 indices.");

            GCHandle?pinnedArrayHandle = null;
            IntPtr   initialDataPtr    = IntPtr.Zero;

            if (InitialData != null)
            {
                pinnedArrayHandle = GCHandle.Alloc(InitialData.Value.ContainingArray, GCHandleType.Pinned);
                initialDataPtr    = pinnedArrayHandle.Value.AddrOfPinnedObject() + (IndexBuffer.INDEX_SIZE_BYTES * (int)InitialData.Value.Offset);
            }

            try {
                BufferResourceHandle outResourceHandle;
                InteropUtils.CallNative(NativeMethods.ResourceFactory_CreateIndexBuffer,
                                        RenderingModule.Device,
                                        length,
                                        Usage.GetUsage(),
                                        Usage.GetCPUUsage(),
                                        initialDataPtr,
                                        (IntPtr)(&outResourceHandle)
                                        ).ThrowOnFailure();

                return(new IndexBuffer(outResourceHandle, Usage, length));
            }
            finally {
                if (pinnedArrayHandle != null)
                {
                    pinnedArrayHandle.Value.Free();
                }
            }
        }
Пример #12
0
 internal static void DestroyRigidBody(PhysicsBodyHandle body)
 {
     LosgapSystem.InvokeOnMasterAsync(() => InteropUtils.CallNative(
                                          NativeMethods.PhysicsManager_DestroyRigidBody,
                                          body
                                          ).ThrowOnFailure());
 }
Пример #13
0
        public string GetInteropWif(Nexus nexus, PhantasmaKeys nodeKeys, string platformName)
        {
            var genesisHash = nexus.GetGenesisHash(nexus.RootStorage);
            var interopKeys = InteropUtils.GenerateInteropKeys(nodeKeys, genesisHash, platformName);
            var defaultWif  = interopKeys.ToWIF();

            string customWIF = null;

            SwapPlatformChain targetChain;

            if (Enum.TryParse(platformName, true, out targetChain))
            {
                var platform = this.Oracle.SwapPlatforms.FirstOrDefault(x => x.Chain == targetChain);

                if (platform != null)
                {
                    customWIF = platform.WIF;
                }
            }

            var result = !string.IsNullOrEmpty(customWIF) ? customWIF: defaultWif;

            if (result != null && result.Length == 64)
            {
                var temp = new PhantasmaKeys(Base16.Decode(result));
                result = temp.ToWIF();
            }

            return(result);
        }
Пример #14
0
        /// <summary>
        /// Constructor.  Creates a device capable of operating on any of the protocols the device
        /// stack supports as standard but with no services or attributes as yet
        /// </summary>
        /// <param name="aUdn">Universally unique identifier.  The caller is responsible for calculating/assigning this</param>
        public unsafe DvDeviceStandard(string aUdn)
        {
            IntPtr udn = InteropUtils.StringToHGlobalUtf8(aUdn);

            iHandle = DvDeviceStandardCreateNoResources(udn);
            Marshal.FreeHGlobal(udn);
        }
Пример #15
0
        private WindowsCredential CreateCredentialFromStructure(Win32Credential credential)
        {
            string password = null;

            if (credential.CredentialBlobSize != 0 && credential.CredentialBlob != IntPtr.Zero)
            {
                byte[] passwordBytes = InteropUtils.ToByteArray(
                    credential.CredentialBlob,
                    credential.CredentialBlobSize);
                password = Encoding.Unicode.GetString(passwordBytes);
            }

            // Recover the target name we gave from the internal (raw) target name
            string targetName = credential.TargetName.TrimUntilIndexOf(TargetNameLegacyGenericPrefix);

            // Recover the service name from the target name
            string serviceName = targetName;

            if (!string.IsNullOrWhiteSpace(_namespace))
            {
                serviceName = serviceName.TrimUntilIndexOf($"{_namespace}:");
            }

            // Strip any userinfo component from the service name
            serviceName = RemoveUriUserInfo(serviceName);

            return(new WindowsCredential(serviceName, credential.UserName, password, targetName));
        }
Пример #16
0
        protected void CopyTo(BaseResource dest)
        {
            Assure.NotNull(dest);
            Assure.NotEqual(this, dest, "Can not copy to self.");
            Assure.Equal(Size, dest.Size, "Resources must be of equal size.");
            Assure.Equal(GetType(), dest.GetType(), "Resources must be of equal type.");

            dest.ThrowIfCannotBeCopyDestination();

            lock (InstanceMutationLock) {
                if (IsDisposed)
                {
                    Logger.Warn("Attempted copy manipulation from disposed resource of type: " + GetType().Name);
                    return;
                }
                lock (dest.InstanceMutationLock) {
                    if (dest.IsDisposed)
                    {
                        Logger.Warn("Attempted copy manipulation to disposed resource of type: " + GetType().Name);
                        return;
                    }
                    InteropUtils.CallNative(
                        NativeMethods.ResourceFactory_CopyResource,
                        RenderingModule.DeviceContext,
                        ResourceHandle,
                        dest.ResourceHandle
                        ).ThrowOnFailure();
                }
            }
        }
Пример #17
0
        protected void CopyTo(BaseResource dest, SubresourceBox srcBox, uint srcSubresourceIndex, uint dstSubresourceIndex,
                              uint dstX, uint dstY, uint dstZ)
        {
            Assure.NotNull(dest);
            Assure.False(this == dest && srcSubresourceIndex == dstSubresourceIndex, "Can not copy to/from same subresource.");
            dest.ThrowIfCannotBeCopyDestination();

            lock (InstanceMutationLock) {
                if (IsDisposed)
                {
                    Logger.Warn("Attempted copy manipulation from disposed resource of type: " + GetType().Name);
                    return;
                }
                lock (dest.InstanceMutationLock) {
                    if (IsDisposed)
                    {
                        Logger.Warn("Attempted copy manipulation to disposed resource of type: " + GetType().Name);
                        return;
                    }
                    InteropUtils.CallNative(
                        NativeMethods.ResourceFactory_CopySubresourceRegion,
                        RenderingModule.DeviceContext,
                        ResourceHandle,
                        srcSubresourceIndex,
                        (IntPtr)(&srcBox),
                        dest.ResourceHandle,
                        dstSubresourceIndex,
                        dstX,
                        dstY,
                        dstZ
                        ).ThrowOnFailure();
                }
            }
        }
        private void Mutate_MapRead(Action <IntPtr> mappedDataReadAction, ResourceMapping readType)
        {
            lock (InstanceMutationLock) {
                if (IsDisposed)
                {
                    Logger.Warn("Attempted read manipulation on disposed resource of type: " + GetType().Name);
                    return;
                }
                IntPtr outDataPtr;
                uint   outUnused;
                InteropUtils.CallNative(
                    NativeMethods.ResourceFactory_MapSubresource,
                    RenderingModule.DeviceContext,
                    ResourceHandle,
                    0U,
                    readType,
                    (IntPtr)(&outDataPtr),
                    (IntPtr)(&outUnused),
                    (IntPtr)(&outUnused)
                    ).ThrowOnFailure();

                try {
                    mappedDataReadAction(outDataPtr);
                }
                finally {
                    InteropUtils.CallNative(
                        NativeMethods.ResourceFactory_UnmapSubresource,
                        RenderingModule.DeviceContext,
                        ResourceHandle,
                        0U
                        ).ThrowOnFailure();
                }
            }
        }
Пример #19
0
        public string GetInteropWif(Nexus nexus, PhantasmaKeys nodeKeys, string platformName)
        {
            var genesisHash = nexus.GetGenesisHash(nexus.RootStorage);
            var interopKeys = InteropUtils.GenerateInteropKeys(nodeKeys, genesisHash, platformName);
            var defaultWif  = interopKeys.ToWIF();

            string customWIF = null;

            switch (platformName)
            {
            case "neo":
                customWIF = this.Oracle.NeoWif;
                break;


            case "ethereum":
                customWIF = this.Oracle.EthWif;
                break;
            }

            var result = !string.IsNullOrEmpty(customWIF) ? customWIF: defaultWif;

            if (result != null && result.Length == 64)
            {
                var temp = new PhantasmaKeys(Base16.Decode(result));
                result = temp.ToWIF();
            }

            return(result);
        }
Пример #20
0
        /// <summary>
        /// Creates a new view to this buffer.
        /// </summary>
        /// <param name="firstElementIndex">The index of the first element in this buffer that will be accessible through the returned view.</param>
        /// <param name="numElements">The number of elements in this buffer that will be accessible through the returned view.</param>
        /// <returns>A new resource view that permits reading data from this buffer.</returns>
        public unsafe ShaderBufferResourceView CreateView(uint firstElementIndex, uint numElements)
        {
            if (firstElementIndex + numElements > Length || numElements == 0U)
            {
                throw new ArgumentOutOfRangeException("numElements");
            }
            if ((PermittedBindings & GPUBindings.ReadableShaderResource) != GPUBindings.ReadableShaderResource)
            {
                throw new InvalidOperationException("Can not create an shader resource view to a resource that was created without the "
                                                    + GPUBindings.ReadableShaderResource + " binding.");
            }

            ShaderResourceViewHandle outViewHandle;

            InteropUtils.CallNative(
                NativeMethods.ResourceFactory_CreateSRVToBuffer,
                RenderingModule.Device,
                (BufferResourceHandle)ResourceHandle,
                GetFormatForType(ElementType),
                firstElementIndex,
                numElements,
                (IntPtr)(&outViewHandle)
                ).ThrowOnFailure();

            return(new ShaderBufferResourceView(outViewHandle, this, firstElementIndex, numElements));
        }
Пример #21
0
        private static int WriteResource(IntPtr aUserData, IntPtr aUriTail, uint aInterface, IntPtr aLanguageList, IntPtr aWriterData,
                                         CallbackWriteResourceBegin aWriteBegin,
                                         CallbackWriteResource aWriteResource,
                                         CallbackWriteResourceEnd aWriteEnd)
        {
            GCHandle         gch          = GCHandle.FromIntPtr(aUserData);
            DvDeviceStandard self         = (DvDeviceStandard)gch.Target;
            string           uriTail      = InteropUtils.PtrToStringUtf8(aUriTail);
            List <string>    languageList = new List <string>();
            uint             count        = DvResourceWriterLanguageCount(aLanguageList);

            for (uint i = 0; i < count; i++)
            {
                languageList.Add(InteropUtils.PtrToStringUtf8(DvResourceWriterLanguage(aLanguageList, i)));
            }
            ResourceWriter writer = new ResourceWriter(aWriterData, aWriteBegin, aWriteResource, aWriteEnd);

            try
            {
                writer.Write(self.iResourceManager, uriTail, aInterface, languageList);
            }
            catch
            {
                return(-1);
            }
            return(0);
        }
Пример #22
0
        /// <summary>
        /// Constructor.  Creates a device without support for any protocol but capable of adding services or attributes.
        /// This should only be used with CpDeviceDv.
        /// </summary>
        /// <param name="aUdn">Universally unique identifier.  The caller is responsible for calculating/assigning this</param>
        public unsafe DvDevice(string aUdn)
        {
            IntPtr udn = InteropUtils.StringToHGlobalUtf8(aUdn);

            iHandle = DvDeviceCreate(udn);
            Marshal.FreeHGlobal(udn);
            iCallbackDisabled = new DisabledCallback(Disabled);
        }
Пример #23
0
        /// <summary>
        /// Set the value of an unsigned integer output argument for an invocation.
        /// </summary>
        /// <param name="aName">Name of the parameter associated with this output argument</param>
        /// <param name="aValue">Value of the output argument</param>
        public void WriteUint(String aName, uint aValue)
        {
            IntPtr name = InteropUtils.StringToHGlobalUtf8(aName);
            int    err  = DvInvocationWriteUint(iHandle, name, aValue);

            Marshal.FreeHGlobal(name);
            CheckError(err);
        }
Пример #24
0
 internal unsafe static void RemoveAllForceAndTorqueFromBody(PhysicsBodyHandle body)
 {
     LosgapSystem.InvokeOnMasterAsync(() => {
         InteropUtils.CallNative(NativeMethods.PhysicsManager_RemoveAllForceAndTorqueFromBody,
                                 body
                                 ).ThrowOnFailure();
     });
 }
Пример #25
0
 internal static void SetBodyMass(PhysicsBodyHandle body, float newMass)
 {
     LosgapSystem.InvokeOnMasterAsync(() => InteropUtils.CallNative(
                                          NativeMethods.PhysicsManager_SetBodyMass,
                                          body,
                                          newMass
                                          ).ThrowOnFailure());
 }
Пример #26
0
        /// <summary>
        /// Query the unique identifier associated with a device
        /// </summary>
        /// <returns>Device's (universally unique) name</returns>
        public String Udn()
        {
            IntPtr ptr;
            uint   len;

            CpDeviceCGetUdn(iHandle, out ptr, out len);
            return(InteropUtils.PtrToStringUtf8(ptr, len));
        }
Пример #27
0
        /// <summary>
        /// Report an error reading or writing an invocation
        /// </summary>
        /// <remarks>Must be called if ReadEnd() isn't reached.
        /// May be called if WriteStart() or later have been called.</remarks>
        /// <param name="aCode">Error code</param>
        /// <param name="aDescription">Error description</param>
        public void ReportError(uint aCode, String aDescription)
        {
            IntPtr desc = InteropUtils.StringToHGlobalUtf8(aDescription);

            // no point in propogating any error - client code can't cope with error reporting failing
            DvInvocationReportError(iHandle, aCode, desc);
            Marshal.FreeHGlobal(desc);
        }
Пример #28
0
        /// <summary>
        /// Query the value of an atrribute
        /// </summary>
        /// <param name="aKey">string of the form protocol_name.protocol_specific_key.
        /// Commonly used keys are published ... (!!!! where?)</param>
        /// <param name="aValue">string containing the attribute or null if the attribute has not been set.</param>
        public unsafe void GetAttribute(string aKey, out string aValue)
        {
            IntPtr key = InteropUtils.StringToHGlobalUtf8(aKey);
            char * value;

            DvDeviceGetAttribute(iHandle, key, &value);
            Marshal.FreeHGlobal(key);
            aValue = InteropUtils.PtrToStringUtf8((IntPtr)value);
        }
Пример #29
0
        protected virtual Boolean Set(String key, String value, String section)
        {
            if (WritePrivateProfileString(section, key, value, Path) == 0)
            {
                InteropUtils.ThrowLastWin32Exception();
            }

            return(true);
        }
Пример #30
0
        /// <summary>
        /// Set the value of an attribute
        /// </summary>
        /// <param name="aKey">string of the form protocol_name.protocol_specific_key</param>
        /// <param name="aValue">attribute will be set to a copy of this string</param>
        public unsafe void SetAttribute(string aKey, string aValue)
        {
            IntPtr key   = InteropUtils.StringToHGlobalUtf8(aKey);
            IntPtr value = InteropUtils.StringToHGlobalUtf8(aValue);

            DvDeviceSetAttribute(iHandle, key, value);
            Marshal.FreeHGlobal(key);
            Marshal.FreeHGlobal(value);
        }