2013-07-10 2 views
6

は構造体ですが、私は、呼び出し側が同様の方法にnull(またはIntPtr.Zero)を通過できるようにする必要があります。構造体にIntPtrを取得するには?私は署名</p> <pre><code>public int Copy(Texture texture, Rect? srcrect, Rect? dstrect) </code></pre> <p><code>Rect</code>と方法を持っている

私はその後、私は次のように行うことができます願っていた署名

[DllImport("SDL2.dll", CallingConvention = CallingConvention.Cdecl, EntryPoint = "SDL_RenderCopy")] 
internal static extern int RenderCopy(IntPtr renderer, IntPtr texture, IntPtr srcrect, IntPtr dstrect); 

でDLLにそれを渡したい

return SDL.RenderCopy(_ptr, texture._ptr, srcrect.HasValue ? (IntPtr)srcrect.Value : IntPtr.Zero, dstrect.HasValue ? (IntPtr)dstrect.Value : IntPtr.Zero); 

をしかし、私は構造体をキャストすることはできませんそうですね。それ以外の方法で私はIntPtrを得ることができますか?得ることができる

  • ref Rect, ref Rect
  • IntPtr, IntPtr
  • ref Rect, IntPtr
  • IntPtr, ref Rect


あり、代替は4つのオーバーロードを作成することです2つ以上の構造体ポインタを渡す必要がある場合は、もっと面倒です。


私は解決策を考え出したが、私はそれについていくつか質問がある:

public int Copy(Texture texture, Rect? srcrect=null, Rect? dstrect=null) 
{ 
    return SDL.RenderCopy(_ptr, texture._ptr, srcrect.HasValue ? StructToPtr(srcrect) : IntPtr.Zero, dstrect.HasValue ? StructToPtr(dstrect) : IntPtr.Zero); 
} 

private static IntPtr StructToPtr(object obj) 
{ 
    var ptr = Marshal.AllocHGlobal(Marshal.SizeOf(obj)); 
    Marshal.StructureToPtr(obj, ptr, false); 
    return ptr; 
} 

は、私は構造体にメモリを割り当てるために持っていないでしょうref Rectを使用していた - ことを何をしますかこれとは違ったやり方はありますか?


私はいくつかの実験を行いました。 ref Rectソリューションは、C#を使用して、REFを使用ボンネットの下に非常によく似た何かをしていると思われるために私をリードRectためIntPtrを生成RectIntPtrに変換と同じ速度、程度で動作します。私がそれをRect?にして、メソッドに条件付きロジックを追加すると、最大50%遅くなります。そのため、4オーバーロードルートがおそらく最も速くなります。しかし、我々は100K回の反復に対して100〜150msを話している。つまり、メソッド自体が非常に安価であるということであり、おそらく条件式に大きな影響があるのだろう。そのように、私は自分のカスタムStructToPtrソリューションを使用しています。最も簡単なソリューションです。

+0

あなたのタイトルはあまりよく言われていません。構造体をIntPtrに変換することはできません。ただし、構造体へのポインタを取得できます。 –

+0

@JimMischel:True。私は実際にそれを "変換"することを考えていなかった、私はキャストのラインに沿って何かを考えていた。 Cでは、変数の前に '&'をスラップしてそのアドレスを得ることができます。 – mpen

答えて

7

Marshal.StructureToPtrを使用します。

また、構造体のメモリを割り当てたり、割り当てを解除したりする必要があります。

HRESULT C_API(LPCWSTR name, PSTRUCT_WHATEVER *ppStruct); 

テーマに良いブログはここhttp://www.developerfusion.com/article/84519/mastering-structs-in-c/

+0

3つのパラメータが必要です。私はそれのために記憶をあらかじめ割り当てなければならないようです。 – mpen

+0

ええ、それについて申し訳ありません。私は答えを編集し、あなたにブログを指摘しました。 –

+0

もう少し検索しましたが、もっと良い解決策が見つかるでしょう:http://stackoverflow.com/questions/1049623/how-to-pass-a-nullable-type-to-ap-invoked-function –

-2

で発見することができますが、私は、私はM $ DLLからAPIを使用していているとプロトタイプは次のようである何構造は、次のように定義されますC#ので

typedef struct whatever { 
    LPCWSTR x; 
    LPCWSTR y; 
} 

私は次のように定義しています:

[StructLayout(LayoutKind.Sequential)] 
public class WHATEVER { 
    public IntPtr x; 
    public IntPtr y; 
} 

[DllImport("msdll.dll", SetLastError=false, CharSet=CharSet.Unicode)] 
    public static extern long C_API(String name, out IntPtr ppStruct); 

それを使用するには、次の

IntPtr s;   
long HR = C_API("myname", out s); 

WHATEVER pInfo = (WHATEVER) Marshal.PtrToStructure(s, typeof(WHATEVER)); 

String mystring = Marshal.PtrToStringAuto(pInfo.x); 

この時点でのMyStringで= "これは文字列です";

関連する問題

 関連する問題