如何将IntPtr转换为byte*

11

我通过Interop调用一个方法,该方法返回一个out IntPtr参数。如何获取这个IntPtrbyte*,以便我可以对其进行操作?我尝试了以下代码:

fixed(byte* ptr = (byte)myIntPtr)

但它没有起作用。任何帮助都将不胜感激!


1
嗨,Dmitri,你可以请求更多信息或接受一个答案吗? - Jb Evain
5个回答

20

您可以简单地编写:

byte* ptr = (byte*)int_ptr;

您不必使用fixed关键字。您不想固定IntPtr,是吗?


这也可以正常工作,但个人而言,我更喜欢使用ToPointer方法,特别是如果您不需要立即将其转换为特定类型指针(例如从void到byte)。 - Noldorin

8

myIntPtr.ToPointer()


1
请注意,在这种情况下,fixed关键字并不是很合适,因为它用于防止变量的重定位。由于IntPtr已经是(托管)指针,因此您实际上只需要在两种类型之间进行直接转换。另请参阅http://msdn.microsoft.com/en-us/library/f58wzh21(VS.71).aspx。 - Noldorin
3
在这种情况下,IntPtr并不是托管指针,而是非托管指针! - Anton Tykhyy
1
是的,我的意思是IntPtr是托管指针,因为它是托管库的一部分,而byte*是不安全的C风格指针。也许“安全”是一个更好的词,但需要注意IntPtr和SafeHandle之间的区别。 - Noldorin
IntPtr 也不是非常安全的,因为你可以将它从/转换为整数。无论如何,有很多遗留的 API 需要处理,所以 IntPtr 不会很快消失。 - Anton Tykhyy
是的,Win32互操作编程非常基础。我认为我已经表明了IntPtr并不是很安全(取决于你使用哪个意义的单词)-但至少它不像指针那样需要一个不安全的上下文。 - Noldorin

3

我不希望我的应用程序中出现“不安全代码”,因此我采取了以下措施将IntPtr转换为byte[]。给定一个名为“unsafeDataBlock”的IntPtr:

var byteArray = new byte[dataBlockSize];
System.Runtime.InteropServices.Marshal.Copy(unsafeDataBlock, byteArray, 0, dataBlockSize);

2

对我来说,这似乎有效。我没有使用Interop,但仍然从C#调用了一个托管的C++函数。然而,托管的C++函数调用了非托管代码,因此它实现了与Interop相同的功能。

无论如何,在从C#调用的C++函数中,我使用了以下代码:

(anyPointerType*) pointer = (anyPointertype*) myIntPtr.ToPointer();

1
只是想澄清我的意思: “我没有使用Interop,但仍然从C#调用了一个托管的C++函数。然而,这个托管的C++函数调用了非托管代码,所以它实现了与Interop相同的功能。”通过Interop调用非托管代码: C# -(使用Interop调用)> 非托管代码 与 从C#调用一个调用非托管代码的托管C++函数: C# -(调用)> 托管C++函数 -(调用)> 非托管代码 具有相同的结果,而后者通常更容易。 - JD.

1
如果你不想在你的应用程序中使用不安全的代码,你将需要使用System.Runtime.InteropServices.Marshal中的方法,或者(更好的选择)声明你的互操作函数的参数类型,以便自动进行封送处理。

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接