CppSharp icon indicating copy to clipboard operation
CppSharp copied to clipboard

Vtables

Open upretyrohan opened this issue 3 years ago • 2 comments

What is the use of SetupVTables() method generated for each class during C++ conversion to C#. What does protected void[] __OriginalVTables; private static void[] _Thunks; private static void*[] __ManagedVTables; store

upretyrohan avatar Feb 23 '22 11:02 upretyrohan

Those members provide the machinery necessary to allow overriding the C++ virtual methods from C#.

They store the original virtual tables setup by C++, which we then manipulate to contain pointers to the thunks created by the .NET runtime that provide the transitions between the native and managed world.

tritao avatar Feb 23 '22 16:02 tritao

Thanks, I want to understand more. Here SetObject and SetObject1 are virtual methods in unmanaged world. __OriginalVTables stores vtable pointer, right? What is the use of _SetObjectDelegateHook and _SetObject1DelegateHook . There are never invoked as per what i found while debugging

        private void SetupVTables(bool destructorOnly = false)
        {
            if (__OriginalVTables != null)
                return;
            __OriginalVTables = new void*[] { *(void**) (__Instance + 0) };

            if (destructorOnly)
                return;
            if (_Thunks == null)
            {
                _Thunks = new void*[2];
                _SetObjectDelegateInstance += _SetObjectDelegateHook;
                _Thunks[0] = Marshal.GetFunctionPointerForDelegate(_SetObjectDelegateInstance).ToPointer();
                _SetObject1DelegateInstance += _SetObject1DelegateHook;
                _Thunks[1] = Marshal.GetFunctionPointerForDelegate(_SetObject1DelegateInstance).ToPointer();
            }

            if (__ManagedVTables == null)
            {
                __ManagedVTables = new void*[1];
                var vfptr0 = Marshal.AllocHGlobal(2 * 4);
                __ManagedVTables[0] = vfptr0.ToPointer();
                *(void**) (vfptr0 + 0) = _Thunks[0];
                *(void**) (vfptr0 + 4) = _Thunks[1];
            }

            *(void**) (__Instance + 0) = __ManagedVTables[0];
        }

upretyrohan avatar Feb 28 '22 14:02 upretyrohan