Sign Up

Sign Up to our social questions and Answers Engine to ask questions, answer people’s questions, and connect with other people.

Have an account? Sign In

Have an account? Sign In Now

Sign In

Login to our social questions & Answers Engine to ask questions answer people’s questions & connect with other people.

Sign Up Here

Forgot Password?

Don't have account, Sign Up Here

Forgot Password

Lost your password? Please enter your email address. You will receive a link and will create a new password via email.

Have an account? Sign In Now

You must login to ask a question.

Forgot Password?

Need An Account, Sign Up Here

Please briefly explain why you feel this question should be reported.

Please briefly explain why you feel this answer should be reported.

Please briefly explain why you feel this user should be reported.

Sign InSign Up

The Archive Base

The Archive Base Logo The Archive Base Logo

The Archive Base Navigation

  • SEARCH
  • Home
  • About Us
  • Blog
  • Contact Us
Search
Ask A Question

Mobile menu

Close
Ask a Question
  • Home
  • Add group
  • Groups page
  • Feed
  • User Profile
  • Communities
  • Questions
    • New Questions
    • Trending Questions
    • Must read Questions
    • Hot Questions
  • Polls
  • Tags
  • Badges
  • Buy Points
  • Users
  • Help
  • Buy Theme
  • SEARCH
Home/ Questions/Q 8966053
In Process

The Archive Base Latest Questions

Editorial Team
  • 0
Editorial Team
Asked: June 15, 20262026-06-15T16:56:32+00:00 2026-06-15T16:56:32+00:00

UPDATE: There is now an accepted answer that works. You should never, ever, ever,

  • 0

UPDATE: There is now an accepted answer that “works”. You should never, ever, ever, ever use it. Ever.


First let me preface my question by stating that I’m a game developer. There’s a legitimate – if highly unusual – performance-related reason for wanting to do this.


Say I have a C# class like this:

class Foo
{
    public int a, b, c;
    public void MyMethod(int d) { a = d; b = d; c = a + b; }
}

Nothing fancy. Note that it is a reference type that contains only value types.

In managed code I’d like to have something like this:

Foo foo;
foo = Voodoo.NewInUnmanagedMemory<Foo>(); // <- ???
foo.MyMethod(1);

What would the function NewInUnmanagedMemory look like? If it can’t be done in C#, could it be done in IL? (Or maybe C++/CLI?)

Basically: Is there a way – no matter how hacky – to turn some totally arbitrary pointer into an object reference. And – short of making the CLR explode – damn the consequences.

(Another way to put my question is: “I want to implement a custom allocator for C#”)

This leads to the follow-up question: What does the garbage collector do (implementation-specific, if need be) when faced with a reference that points outside of managed memory?

And, related to that, what would happen if Foo had a reference as a member field? What if it pointed at managed memory? What if it only ever pointed at other objects allocated in unmanaged memory?

Finally, if this is impossible: Why?


Update: Here are the “missing pieces” so far:

#1: How to convert an IntPtr to an object reference? It might be possible though unverifiable IL (see comments). So far I’ve had no luck with this. The framework seems to be extremely careful to prevent this from happening.

(It would also be nice to be able to get the size and layout information for non-blittable managed types at runtime. Again, the framework tries to make this impossible.)

#2: Assuming problem one can be solved – what does the GC do when it encounters an object reference that points outside of the GC heap? Does it crash? Anton Tykhyy, in his answer, guesses that it will. Given how careful the framework is to prevent #1, it does seem likely. Something that confirms this would be nice.

(Alternatively the object reference could point to pinned memory inside the GC heap. Would that make a difference?)

Based on this, I’m inclined to think that this idea for a hack is impossible – or at least not worth the effort. But I’d be interested to get an answer that goes into the technical details of #1 or #2 or both.

  • 1 1 Answer
  • 0 Views
  • 0 Followers
  • 0
Share
  • Facebook
  • Report

Leave an answer
Cancel reply

You must login to add an answer.

Forgot Password?

Need An Account, Sign Up Here

1 Answer

  • Voted
  • Oldest
  • Recent
  • Random
  1. Editorial Team
    Editorial Team
    2026-06-15T16:56:33+00:00Added an answer on June 15, 2026 at 4:56 pm

    I have been experimenting creating classes in unmanaged memory. It is possible but has a problem I am currently unable to solve – you can’t assign objects to reference-type fields -see edit at the bottom-, so you can have only structure fields in your custom class.
    This is evil:

    using System;
    using System.Reflection.Emit;
    using System.Runtime.InteropServices;
    
    public class Voodoo<T> where T : class
    {
        static readonly IntPtr tptr;
        static readonly int tsize;
        static readonly byte[] zero;
    
        public static T NewInUnmanagedMemory()
        {
            IntPtr handle = Marshal.AllocHGlobal(tsize);
            Marshal.Copy(zero, 0, handle, tsize);
            IntPtr ptr = handle+4;
            Marshal.WriteIntPtr(ptr, tptr);
            return GetO(ptr);
        }
    
        public static void FreeUnmanagedInstance(T obj)
        {
            IntPtr ptr = GetPtr(obj);
            IntPtr handle = ptr-4;
            Marshal.FreeHGlobal(handle);
        }
    
        delegate T GetO_d(IntPtr ptr);
        static readonly GetO_d GetO;
        delegate IntPtr GetPtr_d(T obj);
        static readonly GetPtr_d GetPtr;
        static Voodoo()
        {
            Type t = typeof(T);
            tptr = t.TypeHandle.Value;
            tsize = Marshal.ReadInt32(tptr, 4);
            zero = new byte[tsize];
    
            DynamicMethod m = new DynamicMethod("GetO", typeof(T), new[]{typeof(IntPtr)}, typeof(Voodoo<T>), true);
            var il = m.GetILGenerator();
            il.Emit(OpCodes.Ldarg_0);
            il.Emit(OpCodes.Ret);
            GetO = m.CreateDelegate(typeof(GetO_d)) as GetO_d;
    
            m = new DynamicMethod("GetPtr", typeof(IntPtr), new[]{typeof(T)}, typeof(Voodoo<T>), true);
            il = m.GetILGenerator();
            il.Emit(OpCodes.Ldarg_0);
            il.Emit(OpCodes.Ret);
            GetPtr = m.CreateDelegate(typeof(GetPtr_d)) as GetPtr_d;
        }
    }
    

    If you care about memory leak, you should always call FreeUnmanagedInstance when you are done with your class.
    If you want more complex solution, you can try this:

    using System;
    using System.Reflection.Emit;
    using System.Runtime.InteropServices;
    
    
    public class ObjectHandle<T> : IDisposable where T : class
    {
        bool freed;
        readonly IntPtr handle;
        readonly T value;
        readonly IntPtr tptr;
    
        public ObjectHandle() : this(typeof(T))
        {
    
        }
    
        public ObjectHandle(Type t)
        {
            tptr = t.TypeHandle.Value;
            int size = Marshal.ReadInt32(tptr, 4);//base instance size
            handle = Marshal.AllocHGlobal(size);
            byte[] zero = new byte[size];
            Marshal.Copy(zero, 0, handle, size);//zero memory
            IntPtr ptr = handle+4;
            Marshal.WriteIntPtr(ptr, tptr);//write type ptr
            value = GetO(ptr);//convert to reference
        }
    
        public T Value{
            get{
                return value;
            }
        }
    
        public bool Valid{
            get{
                return Marshal.ReadIntPtr(handle, 4) == tptr;
            }
        }
    
        public void Dispose()
        {
            if(!freed)
            {
                Marshal.FreeHGlobal(handle);
                freed = true;
                GC.SuppressFinalize(this);
            }
        }
    
        ~ObjectHandle()
        {
            Dispose();
        }
    
        delegate T GetO_d(IntPtr ptr);
        static readonly GetO_d GetO;
        static ObjectHandle()
        {
            DynamicMethod m = new DynamicMethod("GetO", typeof(T), new[]{typeof(IntPtr)}, typeof(ObjectHandle<T>), true);
            var il = m.GetILGenerator();
            il.Emit(OpCodes.Ldarg_0);
            il.Emit(OpCodes.Ret);
            GetO = m.CreateDelegate(typeof(GetO_d)) as GetO_d;
        }
    }
    
    /*Usage*/
    using(var handle = new ObjectHandle<MyClass>())
    {
        //do some work
    }
    

    I hope it will help you on your path.

    Edit: Found a solution to reference-type fields:

    class MyClass
    {
        private IntPtr a_ptr;
        public object a{
            get{
                return Voodoo<object>.GetO(a_ptr);
            }
            set{
                a_ptr = Voodoo<object>.GetPtr(value);
            }
        }
        public int b;
        public int c;
    }
    

    Edit: Even better solution. Just use ObjectContainer<object> instead of object and so on.

    public struct ObjectContainer<T> where T : class
    {
        private readonly T val;
    
        public ObjectContainer(T obj)
        {
            val = obj;
        }
    
        public T Value{
            get{
                return val;
            }
        }
    
        public static implicit operator T(ObjectContainer<T> @ref)
        {
            return @ref.val;
        }
    
        public static implicit operator ObjectContainer<T>(T obj)
        {
            return new ObjectContainer<T>(obj);
        }
    
        public override string ToString()
        {
            return val.ToString();
        }
    
        public override int GetHashCode()
        {
            return val.GetHashCode();
        }
    
        public override bool Equals(object obj)
        {
            return val.Equals(obj);
        }
    }
    
    • 0
    • Reply
    • Share
      Share
      • Share on Facebook
      • Share on Twitter
      • Share on LinkedIn
      • Share on WhatsApp
      • Report

Sidebar

Related Questions

Update 2022 There is cloud sql proxy now: https://cloud.google.com/sql/docs/mysql/sql-proxy#how-works Old Question I am currently
My requirement is that I want an object (tee) to update if there have
I have a question that I've searched but can't find a definative answer to.
Inspired by this question where there are differing views on SET NOCOUNT... Should we
Bug reported as fixed by Apple, see accepted answer below ... UPDATE MON AUG
I have not marked this question Answered yet. The current accepted answer got accepted
UPDATE - There are a lot of posts regarding the Child actions are not
Update: Is there a way to achieve what I'm trying to do in an
UPDATE Guid.TryParse is available in .NET 4.0 END UPDATE Obviously there is no public
I want to interrupt some specific grails domain class events(read,write,delete,update).Is there any hibernate eventlistner

Explore

  • Home
  • Add group
  • Groups page
  • Communities
  • Questions
    • New Questions
    • Trending Questions
    • Must read Questions
    • Hot Questions
  • Polls
  • Tags
  • Badges
  • Users
  • Help
  • SEARCH

Footer

© 2021 The Archive Base. All Rights Reserved
With Love by The Archive Base

Insert/edit link

Enter the destination URL

Or link to existing content

    No search term specified. Showing recent items. Search or use up and down arrow keys to select an item.