2010-10-25 60 views
1

(我在C#中編碼)管理結構的地址

我想通過API傳遞指向結構的指針。 說結構,

[StructLayout(LayoutKind.Sequential,CharSet= CharSet.Ansi)] 
     public struct PassThisStruct 
     { 
      public Int32 Param1; 
      public Int32 Param2; 
      [MarshalAs(UnmanagedType.ByValArray, SizeConst=13)] 
      public Char[] OutputData; 

     }; 

現在的API聲明是: -

unsafe public delegate Int32 MyAPI(Int16 Something, PassThisStruct* StructPtr); 

即我想通過結構指針結構。

我爲此API做了一個委託,然後從DLL中取回地址並將其存儲在函數指針中。 但是,當我嘗試編譯時,它給我錯誤委託聲明,「無法獲取地址,獲取大小或聲明指向託管空間的指針」。

那麼應該如何傳遞指針呢? 我知道我可以使用「ref」,但是這個API是用C++編寫的,它需要一個結構指針。如果我使用ref,我不能傳遞Null,而且我也會因爲「AccessViolationException」而出錯(這對我來說是一個更大的問題!)。所以我會使用ref只有當我可以擺脫AccessViolationException。

還有一個問題,我可以在這種情況下通過空?如果是,如何?

問候!

+0

我的關於 「AccessViolationException」 問題:http://stackoverflow.com/questions/3958119/pinning-a - 結構 - 避免 - accessviolationexception – Swanand 2010-10-25 11:44:37

+0

我不明白爲什麼你應該得到這個錯誤。沒有使用「託管」類型。也許這是'ByValArray'造成的問題。還要確保'struct'是'fixed'或一個局部變量。 – leppie 2010-10-25 12:19:05

+0

「委託申報」是什麼意思?我沒有看到你的代碼中有這樣的事情。 – leppie 2010-10-25 12:21:40

回答

1

我看到你正在啓動常量字符數組。因此,我將改寫這個結構爲:

[StructLayout(LayoutKind.Sequential,CharSet= CharSet.Ansi)] 
    public unsafe struct PassThisStruct 
    { 
     public Int32 Param1; 
     public Int32 Param2; 
     public fixed char OutputData[3]; 
    }; 

1) 然後我會用IntPtr的PTR = Marshal.StructureToPtr(...);

unsafe public delegate Int32 MyAPI(Int16 Something, PassThisStruct* StructPtr) would change to: 
    public delegate Int32 MyAPI(Int16 Something, IntPtr StructPtr) 

2) 我還沒有試過,但我認爲,你可以這樣做:

unsafe void MyMethod() 
    { 
    PassThisStruct s = new PassThisStruct(); 
    PassThisStruct* sPtr = (PassThisStruct*)s; 

    myAPI(12, sPtr); 
    }