当前位置: 首页 > 编程语言 > C#

如何在C#中实现C ++样式函数指针,而不使用委托分享

时间:2023-04-10 13:43:23 C#

C#学习教程:HowtoimplementC++stylefunctionpointersinC#withoutusingdelegatesC#中的函数指针。是的,我知道C#有自己的等效函数指针(称为委托)概念。但我只是想知道是否可以在C#中使用指针而不使用委托来实现相同的目的。如果在C#中使用指针(使用不安全选项)是完全合法的,并且指针语义几乎类似于C/C++,那么在我看来,也应该可以使用C/C++样式的函数指针。请指导我。是否可以?如果是怎么办?如果不是那么为什么?请注意C#和C/C++中指针用法的相似性,如下例所示/*在C#中使用指针(非常类似于C/C++)*/usingSystem;namespaceUnsafeCodeApplication{classTestPointer{publicunsafestaticvoidMain(){int[]list={10,100,200};fixed(int*ptr=list)/*让我们在指针中有数组地址*/for(inti=0;i<3;i++){Console.WriteLine("Addressoflist[{0}]={1}",i,(int)(ptr+i));Console.WriteLine("列表的值[{0}]={1}",i,*(ptr+i));}控制台.ReadKey();}}}其他答案指出,即使在不安全模式下,C#也没有对函数指针正确的任何内置支持。考虑实现此功能需要什么是很有趣的。实际上,我已经在2010年未发布的C#原型中实现了此功能?当时。也许是2011年。我们决定审查原型,结果发现语法不够令人愉快,用例也不够好,无法证明继续使用该功能是合理的。首先,此功能相对于委托有哪些吸引人的好处?委托是类型安全的,并且很好地捕获了对绑定到其接收者的函数的引用的语义。然而,在某些“系统”场景中——与原始指针首先用于指向内存的场景相同——委托实在太重量级了。它们被垃圾收集,它们增加了收集压力,与指针的大小相比它们是一个大对象,它们在每次调用时都有成本,等等。或者你可能正在构建自己的自定义布局vtable以与一些特别讨厌的东西进行互操作非托管代码,并且您想调用刚刚放入vtable中的函数指针。等等。CLR有必要的指令:calli,指针间接调用。但是C#中没有语法构造会导致C#编译器发出此指令。所以有什么问题?只需添加一些使其被发出的语法,对吗?问题是:什么语法?为确保CLR的物理堆栈保持正确对齐,编译器必须知道通过指针调用的方法的签名。当然,我们已经有了一种机制来说明方法的签名是什么:称为委托,我们拒绝使用这样的东西。另外,请记住,我们在这里讨论的是将要操作的实际物理堆栈,而不是CLR的抽象计算堆栈。被调用函数的签名必须包括,例如,函数指针是cdecl还是syscall。我们挣扎了一段时间才想出一些看起来并不可怕的东西,无论我们尝试哪种方式,它看起来都更可怕。我实际上不记得我们最终为原型实现的符号;我想我可能已经阻止了它。我可能会在我的笔记中找到它,但不幸的是我现在没有时间看。该功能仍在不断出现。C#团队的当前管理层在低级应用程序中使用托管语言有着悠久的历史,因此如果您有强大的用例,现在可能是再次推销它的好时机。在CLR的支持下,C#语言将您限制为安全的不安全代码。函数指针属于不安全的不安全类别,它们很容易使堆栈失衡。这是一个具有长期后果的严重事故,导致代码在事故发生后很长时间内行为不端。这个站点的名字有一个很好的理由,这种错误是SOE因素。甚至C++编译器也会添加运行时检查以验证是否发生了堆栈不平衡。你还有选择。您可以使用Reflection.Emit或C++/CLI来使用原始函数指针。或者通过使用Delegate.DynamicInvoke()实现道德等同。后者总是安全的,CLR执行运行时检查以验证是否传递了足够的参数。这当然是您应该考虑的解决方案,尽管不清楚您为什么要问。委托通过非常微优化的CLR中的大量代码来加快速度。代码与Reflection.Emit相同,但使用机器代码。你无法击败它。不,在C#中,没有什么比C++更接近于表示函数指针了。C#指针可以按如下方式操作:来源:https://msdn.microsoft.com/en-us/library/y31yhkeb.aspx并不总是可以像在本机代码中那样向用户提供指针。C#代码编译为CLR而不是本机代码。在.NET1.1中,有Econo-JIT模式,可以在调用函数后删除函数的本机代码。一个函数在每次被调用时可以有不同的地址。C#没有指向函数的指针,事实上,C#具有指向值类型的指针的唯一原因是为了与C/C++和WinAPI进行互操作。代表为您服务。C#是一种与C++完全不同的编码范式。不要让语义相似性让您感到困惑。两种截然不同的语言,需要截然不同的心态。以上就是C#学习教程:HowtoimplementC++stylefunctionpointersinC#withoutusingdelegates。如果对你有用,需要进一步了解C#学习教程,希望大家多加关注——本文整理自网络,不代表立场。如涉及侵权,请点击右侧联系管理员删除。如需转载请注明出处: