简体   繁体   中英

C# Get Instance of type char*

is it possible to get an instance of an pointer during runtime? Something like:

Type x = typeof(char*);

How do I get a instance of this pointer? The problem is that I only have a Object with an Type inside. And I know that the Type is a pointer. But now I need a instance of the pointer.

You can:

Type typeChar = typeof(char);
Type ptrChar = typeChar.MakePointerType(); // char*

and back:

if (ptrChar.IsPointer)
{
    Type typeChar2 = ptrChar.GetElementType(); // char
}

But perhaps what you want is something different:

public class TestBool
{
    unsafe public void Test(bool* pointer)
    {
        *pointer = true;
    }

    public void Test2(ref bool reference)
    {
        reference = true;
    }
}

public class TestChar
{
    unsafe public void Test(char* pointer)
    {
        *pointer = 'A';
    }

    public void Test2(ref char reference)
    {
        reference = 'B';
    }
}

public static void TestPointer(object obj, Type parType)
{
    var pointerMethod = obj.GetType().GetMethod("Test");

    Type parType2;

    // Non-blittable types aren't directly supported. 
    // See https://msdn.microsoft.com/en-us/library/75dwhxf7.aspx
    // We cheat a little.
    if (parType == typeof(bool))
    {
        parType2 = typeof(byte);
    }
    else if (parType == typeof(char))
    {
        parType2 = typeof(short);
    }
    else if (parType.IsEnum)
    {
        parType2 = Enum.GetUnderlyingType(parType);
    }
    else
    {
        parType2 = parType;
    }

    object obj2 = Activator.CreateInstance(parType2);
    GCHandle handle = default(GCHandle);

    try
    {
        handle = GCHandle.Alloc(obj2, GCHandleType.Pinned);

        pointerMethod.Invoke(obj, new object[] { handle.AddrOfPinnedObject() });
    }
    finally
    {
        if (handle.IsAllocated)
        {
            handle.Free();
        }
    }

    if (parType == typeof(bool))
    {
        obj2 = (byte)obj2 != 0;
    }
    else if (parType == typeof(char))
    {
        obj2 = (char)(short)obj2;
    }
    else if (parType.IsEnum)
    {
        obj2 = Enum.ToObject(parType, obj2);
    }

    Console.WriteLine(obj2);
}

public static void TestReference(object obj, Type parType)
{
    var referenceMethod = obj.GetType().GetMethod("Test2");

    object obj2 = Activator.CreateInstance(parType);
    var pars = new object[] { obj2 };

    referenceMethod.Invoke(obj, pars);

    Console.WriteLine(pars[0]);
}

private static void Main(string[] args)
{
    {
        var obj = new TestBool();
        TestPointer(obj, typeof(bool));
        TestReference(obj, typeof(bool));
    }

    {
        var obj = new TestChar();
        TestPointer(obj, typeof(char));
        TestReference(obj, typeof(char));
    }
}

See how for the TestPointer , ignoring some problems with non-blittable types, I simply use GCHandle to obtain a pointer to the value and then pass it directly to the method. No unsafe code necessary :-)

For TestReference it is much easier: I only need to create the parameters array separately, and then the CLR will put in that array the modified values.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM