【问题标题】:DotNet - What is int*?DotNet - 什么是 int*?
【发布时间】:2011-03-15 09:20:19
【问题描述】:

简单的问题,我导入了一个DLL函数,参数是int*。 当我尝试输入 Method(0) 时,我收到一条错误消息:“int and int* can not convert”。

这是什么意思?

【问题讨论】:

    标签: c# .net pointers


    【解决方案1】:

    这是pointer to an int 的经典 C 表示法。只要一个类型后跟*,它就表示该类型为该类型的pointer。在 C# 中,与在 C 中不同的是,除了在项目属性中启用 unsafe 代码外,您还必须将函数显式定义为 unsafe 才能使用指针。指针类型也不能直接与具体类型互换,因此必须首先获取类型的引用。要在 C#(或 C 和 C++)中获取指向另一种类型(例如 int)的指针,您必须在希望获取指针的变量前面使用取消引用运算符 &(与号):

    unsafe
    {
        int i = 5;
        int* p = &i;
        // Invoke with pointer to i
        Method(p);
    }
    

    “不安全”代码 C#

    以下是一些关于不安全代码和 C# 中指针使用的关键文章。

    【讨论】:

    • @Nate:好点子,我将添加对取消引用运算符的更好解释。
    • 这里有同样的评论:它与不安全的代码无关。参数只是通过引用传递。 C# 中的“ref”关键字。当 JIT 编译器完成它时,它也是 C# 中的一个指针。
    • @Hans:问题是“什么是 int*?”。我提供了这个问题的答案......不是关于以不同方式传递变量的语义的答案。
    【解决方案2】:

    这是一个pointer to an int。通常最好避免在托管代码中使用。您可能想要发布您导入的方法声明。对于这种互操作,一个 IntPtr 通常就足够了。

    【讨论】:

    • 这只是一个通过引用传递的参数。 P/Invoke marshaller 很好地支持它,使用 IntPtr 是错误的。
    • 取决于它的作用。如果它是一个数组,int[] 就是你想要的。如果是句柄,IntPtr 通常是最好的,特别是如果你打算传递 0。如果你想要一个对 int 的实际引用,ref intout int 可能会更好。
    • 如果没有看到方法声明,我将无法猜测一种或另一种方式(参考 vs 数组 vs 指针)。 @Blindy 是对的。取决于被调用的方法。例如,SendMessage 的 LPARAM 通常被编组为 IntPtr,而那个人通常持有一个内存指针(可以表示为 int*)
    【解决方案3】:

    这取决于您使用的语言。在 C# 中,您应该使用“ref”关键字声明参数。在 VB.NET 中,您应该使用 ByRef 关键字。您需要通过传递变量而不是常量来调用它。像这样的:

     int retval = 0;
     Method(ref retval);
     // Do something with retval
     //...
    

    【讨论】:

    • ref 与接受的答案中使用的 & 几乎相同吗?
    • 在抖动完成后,在引擎盖下,是的。
    • 如果他使用的 DLL 的作者决定了 C# 签名Method(int* p),那么他就不能使用您建议的语法Method(ref retval); 调用该方法,对吧? DLL 的作者可以选择签名Method(ref int p),但由于某种原因他们没有选择。 C# 不对 ref int 类型的变量提供“算术”,例如递增到“下一个”地址,就像指针 int* p 所做的那样(如 C# p++ 和其他“不安全”)。跨度>
    猜你喜欢
    • 1970-01-01
    • 2014-09-30
    • 2016-02-26
    • 2011-01-26
    • 1970-01-01
    • 2021-11-29
    • 2017-10-22
    • 2015-06-17
    • 1970-01-01
    相关资源
    最近更新 更多