12

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 はポインター バイトです* imageData

4

7 に答える 7

23

一般に、C# コードvoid*に変換されます。IntPtr

もう少し情報を編集してくださいIntPtr。.NET/C# では、不透明なハンドルのように動作することがよくあります。それを直接逆参照することはできず、そこから「サイズ」情報(たとえば、指している配列のサイズ)を取得することはできません。また、指しているデータ型を伝えようとはしません。まったくポインター。C/C++ コードを C# に変換しているときに が表示された場合は、正確に何を扱っているかがよくわかるvoid*まで、C# コードを使用して記述する必要があります。IntPtr

pinvoke.net サイトにはglTexImage2D、画像データの保存場所に応じて の 2 つのエントリがあります。画像データがマネージドbyte[]イン .NET/C# に格納されている場合は、.NET を渡すバージョンを呼び出します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);
于 2013-03-20T15:36:58.663 に答える
8

最も一般的なのIntPtrは C# です。

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 を使用してIntPtrfrom を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);

From: C# で byte[] から IntPtr を取得する方法

于 2013-03-20T15:37:33.330 に答える
3

Jonathan Dが彼のデータで説明しているように、void*直接使用できないジェネリック型を表すCの方法です。これはCのジェネリックインターフェイスの実装方法であり、C#()と直接同等のSystem.IntPtrものがありますが、C#にはジェネリックデータを処理するためのより良い方法があり、ここでジェネリックデータを渡す必要があるかどうかは不明です。 。

void*画像データを関数に渡すので、C#で表す可能性がいくつかあります。

  • byte[]生の画像データを関数に渡す
  • System.Drawing.Color[,]より高いレベルのポイントデータを処理している場合(可能性は低い)
  • System.Drawing.Imageより高いレベルで画像データを処理したい場合。あなたがそれで逃げることができれば、これはおそらく良い考えです
  • IntPtr低レベルのバッファがあり、関数がデータを処理せずに内部でCAPIに渡す場合。

コードの使用方法と翻訳する部分についての詳細がなければ、ここでこれらのタイプのどれが必要かを判断することは不可能です。

于 2013-03-20T15:50:14.733 に答える
2

imageData型にキャストしている(void*)ので、基本的にコンパイラにこの値を取得して、それが(void*)

私の経験void*から、非特定のタイプへのポインタです。


例をc#に変換する限り、c++でのキャスト方法についてあまり心配する必要はありません。対応するc#関数に正しい型を渡していることを確認してください。

于 2013-03-20T15:36:07.180 に答える
2

すでに述べたように、 IntPtrは同等です。

C# では、安全でないコンテキストでのみポインターを使用できます。たとえば、次のようになります。

void MyMethod(IntPtr ptr)
{
  unsafe
  {
      var vptr = (void*) ptr;
      // do something with the void pointer
  }
}
于 2013-03-20T15:47:00.677 に答える
1

ボイドは実際には何もありません、

voidを使用する方法は3つあります。

  • 引数:int myFunc(void)-関数は何も取りません。

  • 戻り値:void myFunc(int)-関数は何も返しません

  • ジェネリックデータポインタ:void* data-'data'は不明なタイプのデータへのポインタであり、逆参照できません

この場合、その汎用データポインタです。

于 2013-03-20T15:36:37.020 に答える
1

void*未定義の型のオブジェクトへのポインタです。これには、C# でさまざまな表現があります。

  1. アンセーフ コード内のフォーマットされていないポインターとして。
  2. として、これIntPtrは通常、マネージド オブジェクトとアンマネージド オブジェクトの間でポインターをマーシャリングするために使用されます。
  3. object指定されていないが管理対象オブジェクトについて。
于 2013-03-20T15:38:58.997 に答える