C# 中的 void* 是啥? [复制]

Posted

技术标签:

【中文标题】C# 中的 void* 是啥? [复制]【英文标题】:What is void* in C#? [duplicate]C# 中的 void* 是什么? [复制] 【发布时间】:2013-03-20 15:33:57 【问题描述】:

我正在查看 VC++ 6.00 程序的源代码。我需要将此源代码转换为 C#,但我无法理解此示例中的 (void*) 是什么?

glTexImage2D(
     GL_TEXTURE_2D,
     0,
     GL_RGBA8,
     IMAGE_WIDTH,
     IMAGE_HEIGHT,
     0,
     PIXEL_FORMAT,
     GL_UNSIGNED_BYTE,
     (void*)imageData
 );

在这段代码中 imagedata 是一个指针 byte* 图像数据

【问题讨论】:

void* 可以是任何东西。它应该翻译成什么取决于上下文——在你的情况下可能是byte[] 【参考方案1】:

一般情况下,void* 会在 C# 代码中转换为 IntPtr

编辑更多信息:.NET/C# 中的IntPtr 通常表现得像一个不透明的句柄。您不能直接取消引用它,从中获取“大小”信息(例如,您指向的数组的大小),并且它不会尝试告诉您它指向的数据类型 - 或者即使它是指针。当您将 C/C++ 代码转换为 C# 并看到 void* 时,应使用 IntPtr 编写 C# 代码,直到您更好地了解您正在处理的内容。

pinvoke.net 站点有两个glTexImage2D 条目,具体取决于图像数据的存储位置。如果图像数据存储在 .NET/C# 中的托管byte[] 中,则调用传递byte[] 的版本。如果图像数据存储在非托管内存中,而 C# 代码中的数据只有 IntPtr,则调用传递 IntPtr 的版本。

来自pinvoke.net opengl32的示例:

[DllImport(LIBRARY_OPENGL)] protected static extern void glTexImage2D (
    uint target,
    int level, 
    int internalformat, 
    int width, 
    int height, 
    int border, 
    uint format, 
    uint type, 
    byte[] pixels);
[DllImport(LIBRARY_OPENGL)] protected static extern void glTexImage2D (
    uint target, 
    int level, 
    int internalformat, 
    int width, 
    int height, 
    int border, 
    uint format, 
    uint type, 
    IntPtr pixels);

【讨论】:

在这种情况下会起作用吗?我怀疑传入的是一个字节数组。 1+ 因为您是第一个给出真实答案的人,这反映了他想知道 c# 等价物这一事实。 @Beachwalker 也许这有点为时过早。你不能用IntPtr 做很多事情,根据使用情况,另一种类型在这里可能更合适。 @RobertHarvey 这就是我说“一般而言”的原因。有很多具体的案例,每一个都应该以适当的方式处理。互操作代码不是您希望从“我怀疑......”做出决定的领域 @KonradRudolph 样品?在不使用 unsafe 关键字进行互操作时,IntPtr 是最常见的等价物。为什么早熟?其他任何人都没有回答关于 c# 中的等价物的问题,只是写了 (void) 指针是什么。【参考方案2】:

在 C# 中最典型的是 IntPtr

以下是如何从 C# 调用此函数的示例:

Bitmap bitmap = new Bitmap("blah");
Gl.glTexImage2D(Gl.GL_TEXTURE_2D, 0, 4, bitmap.Width, bitmap.Height, 0, Gl.GL_RGBA, Gl.GL_UNSIGNED_BYTE, bitmap.Scan0);

if(bitmap != null) 
    bitmap.Dispose();

来源:http://www.gamedev.net/topic/193827-how-to-use-glglteximage2d--using-csgl-library-in-c/

如果您拥有的是包含有效图像的byte[],您可以将其加载到位图中:

public static Bitmap BytesToBitmap(byte[] byteArray)

    using (MemoryStream ms = new MemoryStream(byteArray))
    
        Bitmap img = (Bitmap)Image.FromStream(ms);
        return img;
    

如果这给您带来麻烦,或者您的数据不是 Win32 库可以处理的,您可以使用 Marshal 直接从 byte[] 给您一个 IntPtr

IntPtr unmanagedPointer = Marshal.AllocHGlobal(bytes.Length);
Marshal.Copy(bytes, 0, unmanagedPointer, bytes.Length);

// Call your function here, passing unmanagedPointer to it

Marshal.FreeHGlobal(unmanagedPointer);

来自: How to get IntPtr from byte[] in C#

【讨论】:

作为答案的好示例,因为它与问题示例(均为 OpenGL)处于相同的上下文中。【参考方案3】:

正如 Jonathan D 在他的数据中解释的那样,void* 是 C 表示不能直接使用的泛型类型的方式。这是 C 实现泛型接口的方式,虽然它在 C# (System.IntPtr) 中具有直接等效项,但您可能想要使用其他东西,因为 C# 具有更好的处理泛型数据的方法,并且不确定您是否需要通过此处为通用数据。

由于您将图像数据传递给函数,因此void* 在 C# 中表示的有几种可能性:

byte[] 将原始图像数据传递给函数 System.Drawing.Color[,] 如果您正在处理更高级别的点数据(不太可能) System.Drawing.Image 如果您想在更高级别上处理图像数据;如果您能侥幸成功,这可能是个好主意 IntPtr 如果您有一个低级缓冲区并且该函数在内部将数据传递给 C API 而不对其自身进行处理。

如果没有关于如何使用代码以及要翻译哪些部分的更多信息,就无法确定您需要哪些类型。

【讨论】:

【参考方案4】:

它将imageData 转换为(void*) 类型,所以基本上是告诉编译器获取这个值并将其视为(void*)

根据我的经验,void* 是一个指向非特定类型的指针。


就将您的示例转换为 c# 而言,您不必太担心在 c++ 中是如何转换的。只需确保将正确的类型传递给相应的 c# 函数即可。

【讨论】:

【参考方案5】:

如前所述,IntPtr 是等价的。

您只能在 c# 中的 unsafe 上下文中使用指针,例如:

void MyMethod(IntPtr ptr)

  unsafe
  
      var vptr = (void*) ptr;
      // do something with the void pointer
  

【讨论】:

【参考方案6】:

void* 是指向未定义类型对象的指针。在 C# 中有多种表示形式:

    作为不安全代码中的未格式化pointer。 作为IntPtr,通常用于在托管对象和非托管对象之间编组指针。 作为object 用于未指定但受管理的对象。

【讨论】:

【参考方案7】:

虚无其实什么都不是,

void的三种使用方式:

参数:int myFunc(void) -- 该函数不接受任何内容。

返回值:void myFunc(int) -- 函数不返回任何内容

通用数据指针:void* data -- 'data' 是指向未知类型数据的指针,不能取消引用

在这种情况下,它是一个通用数据指针。

【讨论】:

这根本没有回答他的问题,我对投票感到困惑。他想知道 C# 中的 void* 等价物是什么,而不是解释什么是 void。 @Adam 作为支持者之一,让我解释一下:我对这个答案并不完全满意(因为你提到的原因),但它是第一个真正解释 void* 是什么的答案,以简洁的方式。如何将它翻译成 C# 取决于它的用法,而 OP 并没有那么公开。

以上是关于C# 中的 void* 是啥? [复制]的主要内容,如果未能解决你的问题,请参考以下文章

C中的'static void *'是啥意思? [复制]

C#中的“var”是啥意思? [复制]

c#中的行为抽象类和接口是啥? [复制]

C++ 中的 <map> 的 C# 等价物是啥? [复制]

将 Enumeration<Integer> for 循环从 Java 转换为 C#? C# 中的 Enumeration<Integer> 到底是啥? [复制]

C++ 中的 :: 是啥意思? [复制]