Pinning an updateble struct before passing to unmanaged code?

后端 未结 6 2051
一个人的身影
一个人的身影 2021-02-04 11:11

I using some old API and need to pass the a pointer of a struct to unmanaged code that runs asynchronous.

In other words, after i passing the struct pointer to the unman

6条回答
  •  日久生厌
    2021-02-04 11:46

    To answer your edit:

    Just thought... is there a way to pin the parent object that contains the struct, and then get the pointer of the struct rather than the container object?

    I think so. If anything, you should be able to with a managed array of structures (possibly an array of one).

    Here is an example code:

        [StructLayout(LayoutKind.Sequential)]
        struct SomeStructure
        {
            public int first;
            public int second;
            public SomeStructure(int first, int second) { this.first=first; this.second=second; }
        }
        
        /// 
        /// For this question on Stack Overflow:
        /// https://stackoverflow.com/questions/1850488/pinning-an-updateble-struct-before-passing-to-unmanaged-code
        /// 
        private static void TestModifiableStructure()
        {
            SomeStructure[] objArray = new SomeStructure[1];
            objArray[0] = new SomeStructure(10, 10);
            
            GCHandle hPinned = GCHandle.Alloc(objArray, GCHandleType.Pinned);
    
            //Modify the pinned structure, just to show we can
            objArray[0].second = 42;
    
            Console.WriteLine("Before unmanaged incrementing: {0}", objArray[0].second);
            PlaceholderForUnmanagedFunction(hPinned.AddrOfPinnedObject());
            Console.WriteLine("Before unmanaged incrementing: {0}", objArray[0].second);
            
            //Cleanup
            hPinned.Free();
        }
        
        //Simulates an unmanaged function that accesses ptr->second
        private static void PlaceholderForUnmanagedFunction(IntPtr ptr)
        {
            int secondInteger = Marshal.ReadInt32(ptr, 4);
            secondInteger++;
            Marshal.WriteInt32(ptr, 4, secondInteger);
        }
    

    And its output:

    Before unmanaged incrementing: 42
    Before unmanaged incrementing: 43
    

提交回复
热议问题