2016-10-19 67 views
0

我一直試圖在C#中編寫這個結構,但是我有兩個最後一行的麻煩。Marshall奇怪C++中的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

相同,基本上我把它轉換成類,你可以使用as結構,只有代表部分如果爲了你的興趣我想 –

+0

明白了,明天就會測試一下。謝謝:) –