什么是C#中的void *?

时间:2013-03-20 15:33:57

标签: c# c++ visual-c++

我正在查看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 * imageData

7 个答案:

答案 0 :(得分:17)

通常,void*将在C#代码中转换为IntPtr

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

pinvoke.net网站有两个glTexImage2D条目,具体取决于图像数据的存储位置。如果图像数据存储在.NET / C#中的托管byte[]中,则调用传递byte[]的版本。如果图像数据存储在非托管内存中,并且您只有IntPtr C#代码中的数据,则调用通过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 :(得分:7)

最典型的是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直接从IntPtr为您提供byte[]

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#

答案 2 :(得分:3)

虚空实际上什么都没有,

有三种使用void的方法:

  • 参数:int myFunc(void) - 该函数不需要任何操作。

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

  • 通用数据指针:void* data - 'data'是指向未知类型数据的指针,无法解除引用

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

答案 3 :(得分:3)

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

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

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

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

答案 4 :(得分:2)

正如已经说过的IntPtr是等效的。

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

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

答案 5 :(得分:1)

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

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


至于将您的示例转换为c#,那么您不必过于担心c ++中的内容是如何被转换的。只需确保将正确的类型传递给相应的c#函数。

答案 6 :(得分:1)

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

  1. 作为未安全代码中未格式化的pointer
  2. 作为IntPtr,通常用于编组托管和非托管对象之间的指针。
  3. 对于未指定但受管理的对象,为object
相关问题