- c - 在位数组中找到第一个零
- linux - Unix 显示有关匹配两种模式之一的文件的信息
- 正则表达式替换多个文件
- linux - 隐藏来自 xtrace 的命令
我正在学习 C# 中的指针,并且很好奇是否可以在 C# 中使用 C++ 样式的函数指针。是的,我知道 C# 有自己的函数指针(称为委托(delegate))的等效概念。但我只想知道是否可以在 C# 中使用指针而不使用委托(delegate)来实现相同的目的。
如果在 C# 中使用指针是完全合法的(使用不安全选项)并且指针语义与 C/C++ 几乎相似,那么在我看来,人们也应该能够使用 C/C++ 风格的函数指针。请指导我。是否可以?如果是,怎么办?如果不是,那又是为什么?
请注意 C# 和 C/C++ 中指针用法的相似性,如下例所示
/* Using pointers in C# (Very similar to C/C++) */
using System;
namespace UnsafeCodeApplication
{
class TestPointer
{
public unsafe static void Main()
{
int[] list = {10, 100, 200};
fixed(int *ptr = list)
/* let us have array address in pointer */
for ( int i = 0; i < 3; i++)
{
Console.WriteLine("Address of list[{0}]={1}",i,(int)(ptr + i));
Console.WriteLine("Value of list[{0}]={1}", i, *(ptr + i));
}
Console.ReadKey();
}
}
}
最佳答案
指出 C# 没有对函数指针的任何内置支持的其他答案是正确的,即使在不安全模式下也是如此。
考虑实现此功能需要做些什么很有趣。碰巧的是,我早在...2010 年就在未发布的 C# 原型(prototype)版本中实现了此功能?那时左右。也许是 2011 年。
我们在审查原型(prototype)后决定,语法不够令人愉快,用例也不够令人信服,无法证明继续使用该功能是合理的。
首先,与委托(delegate)相比,该功能的显着优势是什么?委托(delegate)是类型安全的,并且很好地捕获了对绑定(bind)到其接收者的函数的引用的语义。然而,在某些“系统”场景中——与您首先使用原始内存指针的场景相同——委托(delegate)实在是太重量级了。它们被垃圾收集,它们增加了收集压力,与指针的大小相比它们是一个大对象,它们在每次调用时都有成本,等等。或者,您可能正在构建自己的自定义布局 vtables 以与一些特别讨厌的非托管代码进行互操作,并且您希望调用您刚刚放在 vtable 中的函数指针。等等。
CLR 有必要的指令:calli
,一个指针间接调用。但是 C# 中没有任何语法结构会导致 C# 编译器发出此指令。
那么问题是什么?只需添加一些语法即可发出此消息,对吗?
问题是:什么语法?为了确保 CLR 的物理堆栈保持正确对齐,编译器必须知道通过指针调用的方法的签名。当然,我们已经有了一种机制来说明方法的签名是什么:称为委托(delegate),我们已经拒绝使用这样的东西。此外,请记住,我们在这里谈论的是实际要操作的物理堆栈,而不是 CLR 的抽象计算堆栈。被调用函数的签名必须包括诸如函数指针是 cdecl 还是 syscall 之类的内容。
我们努力想出一些看起来并不可怕的东西,但无论我们尝试哪种方式,它看起来都更可怕。我实际上不记得我们最终为原型(prototype)实现了什么符号;我想我可能已经阻止了它。我可能在我的笔记中的某个地方有它,但不幸的是我现在没有时间看。
该功能仍时不时地出现。 C# 团队的当前管理层有在低级应用程序中使用托管语言的历史,因此如果您有强大的用例,现在可能是再次宣传它的好时机。
关于c# - 如何在 C# 中实现 C++ 风格的函数指针?,不使用委托(delegate),我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/36558996/
C语言sscanf()函数:从字符串中读取指定格式的数据 头文件: ?
最近,我有一个关于工作预评估的问题,即使查询了每个功能的工作原理,我也不知道如何解决。这是一个伪代码。 下面是一个名为foo()的函数,该函数将被传递一个值并返回一个值。如果将以下值传递给foo函数,
CStr 函数 返回表达式,该表达式已被转换为 String 子类型的 Variant。 CStr(expression) expression 参数是任意有效的表达式。 说明 通常,可以
CSng 函数 返回表达式,该表达式已被转换为 Single 子类型的 Variant。 CSng(expression) expression 参数是任意有效的表达式。 说明 通常,可
CreateObject 函数 创建并返回对 Automation 对象的引用。 CreateObject(servername.typename [, location]) 参数 serv
Cos 函数 返回某个角的余弦值。 Cos(number) number 参数可以是任何将某个角表示为弧度的有效数值表达式。 说明 Cos 函数取某个角并返回直角三角形两边的比值。此比值是
CLng 函数 返回表达式,此表达式已被转换为 Long 子类型的 Variant。 CLng(expression) expression 参数是任意有效的表达式。 说明 通常,您可以使
CInt 函数 返回表达式,此表达式已被转换为 Integer 子类型的 Variant。 CInt(expression) expression 参数是任意有效的表达式。 说明 通常,可
Chr 函数 返回与指定的 ANSI 字符代码相对应的字符。 Chr(charcode) charcode 参数是可以标识字符的数字。 说明 从 0 到 31 的数字表示标准的不可打印的
CDbl 函数 返回表达式,此表达式已被转换为 Double 子类型的 Variant。 CDbl(expression) expression 参数是任意有效的表达式。 说明 通常,您可
CDate 函数 返回表达式,此表达式已被转换为 Date 子类型的 Variant。 CDate(date) date 参数是任意有效的日期表达式。 说明 IsDate 函数用于判断 d
CCur 函数 返回表达式,此表达式已被转换为 Currency 子类型的 Variant。 CCur(expression) expression 参数是任意有效的表达式。 说明 通常,
CByte 函数 返回表达式,此表达式已被转换为 Byte 子类型的 Variant。 CByte(expression) expression 参数是任意有效的表达式。 说明 通常,可以
CBool 函数 返回表达式,此表达式已转换为 Boolean 子类型的 Variant。 CBool(expression) expression 是任意有效的表达式。 说明 如果 ex
Atn 函数 返回数值的反正切值。 Atn(number) number 参数可以是任意有效的数值表达式。 说明 Atn 函数计算直角三角形两个边的比值 (number) 并返回对应角的弧
Asc 函数 返回与字符串的第一个字母对应的 ANSI 字符代码。 Asc(string) string 参数是任意有效的字符串表达式。如果 string 参数未包含字符,则将发生运行时错误。
Array 函数 返回包含数组的 Variant。 Array(arglist) arglist 参数是赋给包含在 Variant 中的数组元素的值的列表(用逗号分隔)。如果没有指定此参数,则
Abs 函数 返回数字的绝对值。 Abs(number) number 参数可以是任意有效的数值表达式。如果 number 包含 Null,则返回 Null;如果是未初始化变量,则返回 0。
FormatPercent 函数 返回表达式,此表达式已被格式化为尾随有 % 符号的百分比(乘以 100 )。 FormatPercent(expression[,NumDigitsAfterD
FormatNumber 函数 返回表达式,此表达式已被格式化为数值。 FormatNumber( expression [,NumDigitsAfterDecimal [,Inc
我是一名优秀的程序员,十分优秀!