【问题标题】:trouble using pointers in C#在 C# 中使用指针时遇到问题
【发布时间】:2011-08-21 10:37:18
【问题描述】:

让我们有一个字节数组

byte[] Test = { 0, 0, 0, 0 };

我想这样做:

UInt32* p = &Test[0];
p* = 0xAABBCCDD;

或很快:

(int*)(&Test[0])* = 0xAABBCCDD;

在 Delphi 中我会这样做:

PUInt32(@Test[0])^ := $AABBCCDD;

其中 PUInt32 = ^Uint32 或 typdef PUInt32 = *UInt32 在 C# 中。

但不知道它在 C# 中是如何工作的。

【问题讨论】:

  • 我们在C#中一般不使用指针。
  • WHY!?!?!? 你可以用更简单的方法无法实现的指针做什么??
  • 如果您也能描述所请求解决方案的目的,那将非常有帮助。
  • 快速回答是你几乎可以像在 C/C++ 中那样做,除了你必须做一些特别的事情(比如 fixed 语句)来锁定内存,这样它就不会被垃圾收集...

标签: c# pointers


【解决方案1】:

这种代码根本上是不安全的,它破坏了编译器的类型系统。并且不会被验证者接受。如果您不小心声明了错误的数组,例如 3 个元素,那么您将损坏内存并产生一个很难诊断的错误。

然而,这也可以安全地完成:

byte[] test = BitConverter.GetBytes(0xaabbccdd);

它为您创建数组的轻微缺点。绕过需要不安全的版本:

fixed (byte* ptr = test)
{
    *((uint*)ptr) = 0xaabbccdd;
}

这要求您在方法声明中使用 unsafe 关键字并勾选 Project + Properties, Build, "Allow unsafe code" 选项。

【讨论】:

  • 这就是我一直在寻找的答案。谢谢!
  • +1 是的,我一直忘记 BitConverter,这是一个很酷的课程。 :) 嘿,+♡ 一个参考国际象棋法则的名称,该法则在很大程度上决定了当今游戏的整体特征,但却是业余棋手和业余国际象棋引擎作家中鲜为人知的规则之一: )
【解决方案2】:

您可以在 c# 中使用带有 unsafe 关键字的指针。 http://msdn.microsoft.com/en-us/library/chfa2zb8(v=vs.71).aspx.

但正如其他人建议的那样,不使用指针是更好的方法。

你应该使用不安全的:

实时应用程序,我们可能需要使用指针来提高此类应用程序的性能。 外部函数,在非 .net DLL 中,某些函数需要指针作为参数,例如用 C 编写的 Windows API。 调试,有时我们需要检查内存内容以进行调试,或者您可能需要编写一个应用程序来分析另一个应用程序进程和内存。

http://www.csharpfriends.com/Articles/getArticle.aspx?articleID=351

【讨论】:

  • 咩;总的来说,是的,不要使用指针等......但有时它很有用......做重铸是一件很痛苦的事情,比如说,如果你有一个数据流,你得到了你必须去的地方从 BigEndian 转换为 LittleEndian,以便您阅读。 (真实故事)将其读入结构要容易得多,将 int 的地址转换为 4 个字节 * 并以这种方式进行交换,而不是一堆掩码和移位。呸。 :) YMMV。 (呵呵,如果相关的话,我走了掩蔽和转移路线,完全希望我没有这样做)
  • @shelleybutterfly 是的,您可能是对的,例如数据库驱动的应用程序可能不需要指针。但是一个人正在做一些实时工作,并且对使用指针感到满意,应该毫不犹豫地使用它们。老实说,我忘记了它们是什么 :) 只是地址!
  • @shelley,这是我真正想要做的,因为指针是最快的方式,我想使用它们。但是仍然从这篇文章中我不明白它是如何用类 C 语言完成的。我想将一个无符号整数直接分配给数组的前四个字节(在示例中它的长度为 4)。这怎么可能?
  • 在问题部分查看我的评论,我认为这涵盖了它:)
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2011-12-23
  • 2016-01-20
相关资源
最近更新 更多