2011-12-12 62 views
0

我正在處理一個需要實現非託管Windows DLL的項目。該DLL用於與USB設備進行通信。我的代碼是在C#和WPF中。 要初始化我叫一個叫函數的DLL:從C#WPF應用程序調用非託管Windows DLL時出錯

InitTimerDll(Int32 wHandle, ref dllInitParams initParams); 

當調用這個函數我必須通過結構稱爲dllInitParams與該控件綁定到句柄。 我使用的DllImport爲函數指針爲這樣:

[DllImport("myDll.dll")] 
public static extern void InitTimerDll(Int32 wHandle, ref dllInitParams initParams); 

這裏是我的結構:

public struct dllInitParams 
{ 
    public UInt16 simp; 

    public UInt16 simt; 
} 

以上所有的都在一個單獨的類名爲myDllInterface.cs。下面是我如何調用InitTimerDll功能從我的WPF形式:

public IntPtr Handle 
{ 
    get { return (new System.Windows.Interop.WindowInteropHelper(this)).Handle; } 
} 

private void initTime_Click(object sender, RoutedEventArgs e) 
{ 
    myDllInterface.dllInitParams initParams = new myDllInterface.dllInitParams(); 
    initParams.simp = 0; 
    myDllInterface.InitTimerDll(this.Handle.ToInt32(), ref initParams); 
} 

上面的代碼中的第一部分解釋我是怎麼把手和initTime_Click顯示瞭如何初始化結構,通過將調用initTimeDll功能處理和它的結構。我已經將dll文件複製到運行代碼的目錄中。我的代碼編譯得很好,但是當我單擊initTime按鈕時它會創建一個錯誤。 錯誤:

An unhandled exception of type 'System.AccessViolationException' occurred in ProbeCTRL.exe

Additional information: Attempted to read or write protected memory. This is often an indication that other memory is corrupt.

爲什麼會發生這種情況?

+1

很難說,崩潰的代碼不是您發佈的代碼。您需要調試本機代碼。項目+屬性,調試選項卡,勾選「啓用非託管代碼調試」。在C或C++源代碼中的InitTimerDll函數上設置一個斷點。 –

+1

對於句柄值使用「Int32」而不是「IntPtr」可能會在64位操作系統中導致問題。也可能你的調用約定是錯誤的(.NET中的默認是StdCall)。 – vcsjones

回答

1

不知道InitTimerDll()函數對'this'指針的確切操作,我會關注params結構。嘗試添加如下結構佈局標記:

[StructLayout(LayoutKind.Sequential, Pack=1)] 
public struct dllInitParams 
{ 
    public UInt16 simp; 
    public UInt16 simt; 
} 

此外,請仔細檢查您的結構是否完整和準確。

+0

感謝您的意見。如上所述,我在我的結構中添加了一個layoutKind,並初始化了結構的所有成員。我也改變嘗試傳遞句柄作爲int64和IntPtr。在所有情況下都發生同樣的錯誤你認爲問題可能是由於結構或句柄?不幸的是,我不知道在調用initTimerDll函數時Dll會做什麼,但我知道這是初始化與設備的通信並允許調用其他方法並來回發送數據。任何其他建議將不勝感激。 – user1094315

+0

我不會將Handle擴展到Int64,除非這是DLL API實際需要的。先前有關混合模式32/64位問題的評論不會發生,因爲您無法將32位DLL加載到64位進程中。我還會確保您在擁有該控件的同一線程上調用此函數,因爲跨UI調用UI元素可能會引發異常。 您確定您的DllImport正確嗎?第二個參數是輸入/輸出參數嗎?嘗試從該參數中刪除'ref'。 –

+0

我刪除了「ref」併發送了結構而不是指針,但是我遇到了同樣的錯誤。我沒有做任何多線程。所以我假設該函數在同一個線程上運行。是否有任何方式來驗證這在Visual Studio 2008中? – user1094315

1

我發現了這個問題。代碼很好,問題在於dll文件已損壞。正確的副本的dll文件照顧了這個問題。在代碼中使用dll時,確保您有準確的信息,函數調用,要傳遞的數據類型等是非常重要的。 感謝大家的幫助。

相關問題