2016-10-19 2 views
0

私はこの構造体をC#でマーシャリングしようとしていましたが、最後の2行に問題があります。Marshall Cird in C#

typedef struct _modenv_ 
{ 
    long lMajor;   /* major version of kernel */ 
    long lMinor;   /* minor version of kernel */ 
    long lRelease;  /* release version of kernel */ 

    long lResultSize; /* sResult buffer size */ 

    long (__stdcall *lPGSM_ExecuteKernel) (struct _modenv_ *PGEnv, char *sCommand, char *sResult, long lLength); 
    long (__stdcall *lPGSM_ExecuteCommand)(struct _modenv_ *PGEnv, char *sCommand, char *sResult, long lLength); 

} PGMODENV; 

そして、私が行っているすべてのはこれです:

[StructLayout(LayoutKind.Sequential, CharSet = CharSet.Auto)] 
public struct PGMODENV 
{ 
    /* input data */ 
    public long lMajor;   /* major version of kernel */ 
    public long lMinor;   /* minor version of kernel */ 
    public long lRelease;  /* release version of kernel */ 

    /* updated data */ 
    public long lResultSize; /* sResult buffer size */ 

} 

どのように私はC#でそれらを実装することができますか?

+0

私はこのようなものを見てきました。バッファーが構造体のすぐ後に続くので、構造体をメモリー内に移動できないため、マーシャリングが不可能な場合は驚くことはありません。手掛かりには、バッファサイズは長いが、バッファポインタはまったくない。 – Joshua

+0

これらは関数ポインタです。C#での同等の機能はデリゲートオブジェクトです。注意する必要があります。渡すデリゲートオブジェクトに別の参照がある必要があります。そのため、ネイティブコードが関数呼び出しを行ったときにGCがそれらをクリーンアップしてプログラムをクラッシュさせません。静的変数に格納するか、GCHandle.Alloc()を使用してください。 –

+0

これらの構造体は、エクスポートされた関数の引数として渡されます。これらの構造体はGCですか?どのように私は彼らが収集されるのを防ぐか? –

答えて

-2

機能へのポインタなので、IntPtrを試してみてください。それは次のようになりますように:

[StructLayout(LayoutKind.Sequential, CharSet = CharSet.Auto)] 
public struct PGMODENV 
{ 
    /* input data */ 
    public long lMajor;   /* major version of kernel */ 
    public long lMinor;   /* minor version of kernel */ 
    public long lRelease;  /* release version of kernel */ 

    /* updated data */ 
    public long lResultSize; /* sResult buffer size */ 

    public IntPtr lPGSM_ExecuteKernel; 
    public IntPtr lPGSM_ExecuteCommand; 
} 
+0

引数についてはどうですか? –

+0

これは構造体をマーシャリングするためのものです。その後、Marshal.GetDelegateForFunctionPointerを使用してIntPtrsを@vivek nunaのようなインスタンスを委譲するように変換できます。 –

2
public struct PGMODENV 
{ 
    public int lMajor; // major version of kernel 
    public int lMinor; // minor version of kernel 
    public int lRelease; // release version of kernel 

    public int lResultSize; // sResult buffer size 

    //The original C++ function pointer contained an unconverted modifier: 
    //ORIGINAL LINE: int(__stdcall *lPGSM_ExecuteKernel)(struct _modenv_ *PGEnv, sbyte *sCommand, sbyte *sResult, int lLength); 
    public delegate int lPGSM_ExecuteKernelDelegate(PGMODENV PGEnv, ref string sCommand, ref string sResult, int lLength); 
    public lPGSM_ExecuteKernelDelegate lPGSM_ExecuteKernel; 
    //The original C++ function pointer contained an unconverted modifier: 
    //ORIGINAL LINE: int(__stdcall *lPGSM_ExecuteCommand)(struct _modenv_ *PGEnv, sbyte *sCommand, sbyte *sResult, int lLength); 
    public delegate int lPGSM_ExecuteCommandDelegate(PGMODENV PGEnv, ref string sCommand, ref string sResult, int lLength); 
    public lPGSM_ExecuteCommandDelegate lPGSM_ExecuteCommand; 

} 
+0

これは 'PGMODENV'とは別の構造体であるべきですか? –

+0

基本的に私はクラスに変換しました。構造体として使用することができます。あなたの興味のためにデリゲート部分のみを使用することができます。 –

+0

これを明日テストします。ありがとう:) –