【问题标题】:C# Get Instance of type char*C# 获取 char* 类型的实例
【发布时间】:2015-06-18 12:20:01
【问题描述】:

是否可以在运行时获取指针的实例? 比如:

Type x = typeof(char*);

如何获取此指针的实例?问题是我只有一个里面有一个类型的对象。而且我知道 Type 是一个指针。但现在我需要一个指针的实例。

【问题讨论】:

  • typeof(char).MakePointerType()
  • 这听起来有点奇怪 - 你到底想达到什么目的?
  • 这是我的最后一个问题stackoverflow.com/questions/30911369/… 我想使用反射来调用一个以指针为参数的方法。问题是我只知道运行时的类型。 Jon Skeet 建议我应该使用 Pointer.Box,问题是我需要一个 void* 实例来使用该方法。但正如我所说,我在运行时没有...
  • 使用指针的唯一正当理由(除了用于优化目的的非常晦涩的不安全代码)是调用非托管代码。你在调用非托管代码吗?
  • IntPtr 应该用于将指针作为反射对象传递。

标签: c# pointers runtime instance


【解决方案1】:

你可以:

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

然后返回:

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

但也许你想要的是不同的东西:

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));
    }
}

看看TestPointer 是如何处理的,忽略一些非blittable 类型的问题,我只是简单地使用GCHandle 来获取指向值的指针,然后将它直接传递给方法。不需要不安全的代码:-)

TestReference 就简单多了:我只需要单独创建参数数组,然后 CLR 会将修改后的值放入该数组中。

【讨论】:

  • @Djeurissen 正如 Skeet 所建议的,Pointer.Unbox(ptr) 将返回 void*
  • 确定我之前有没有指针。但是 Pointer.Unbox(' ');不会给我一个字符指针
  • @Djeurissen 不清楚你有什么......尝试编写一个工作示例。
  • @Djeurissen 正如skeet 所写,您的价值在哪里?另一个object
  • 假设我有一个类型变量 Type x = typeof(char*);使用 x.GetElementName() 我得到了引用的类型。在这种情况下,字符。现在我可以像这个 Activator.CreateInstance(x.GetElementType()); 一样创建一个 char 的实例;我现在要做的就是获取一个指向 Activator.CreateInstance 的返回值的指针。但是怎么做?也许我不明白你的问题...
猜你喜欢
  • 2021-03-20
  • 1970-01-01
  • 2019-01-20
  • 2013-07-09
  • 2020-07-23
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多