2015-09-11 114 views
2

我嘗試從C#代碼調用WinAPI函數時出現問題。我有很多進口,其中許多工作正常,但其中一些沒有,並導致意外中斷主程序,沒有任何消息,異常類型,什麼都沒有,只是跌倒了所有的窗口並退出。使用VS 2010調試導入的dll

我有代碼兩種方式:通過我的開發庫,其中更多的是WINAPI電話和我懶,從user32.dll中編寫專門的代碼結構,指針等,並直接導入,如:

[DllImport(@"tradeInterop.dll")] 
    public static extern void ChooseInstrumentByMouse(UInt32 hwnd, int baseX, int baseY, int idx, int _isDown); 
    [DllImport(@"tradeInterop.dll")] 
    public static extern void PutNumber(int num); 
    [DllImport(@"tradeInterop.dll")] 
    public static extern void PutRefresh(); 
    [DllImport(@"user32.dll")] 
    public static extern UInt32 FindWindow(string sClass, string sWindow); 
    [DllImport(@"user32.dll")] 
    public static extern int GetWindowRect(uint hwnd, out RECT lpRect); 
    [DllImport(@"user32.dll")] 
    public static extern int SetWindowPos(uint hwnd, uint nouse, int x, int y, int cx, int cy, uint flags); 
    [DllImport(@"user32.dll")] 
    public static extern int LockSetForegroundWindow(uint uLockCode); 
    [DllImport(@"user32.dll")] 
    public static extern int SetForegroundWindow(uint hwnd); 
    [DllImport(@"user32.dll")] 
    public static extern int ShowWindow(uint hwnd, int cmdShow); 
    [DllImport(@"tradeInterop.dll")] 
    public static extern ulong PixelColor(uint hwnd, int winX, int winY); //tried (signed) long and both ints as return type, same result (WINAPI says DWORD as unsigned long, what about 64-bit assembly where compiled both lib and program? 
    public struct RECT 
    { 
     public int Left;   
     public int Top; ... 

正如我所說的,很多這要求作品完美,但還有最後他們兩個問題:)與下面的代碼的ShowWindow()和PixelColor(:

extern "C" __declspec(dllexport) COLORREF __stdcall PixelColor(unsigned hwnd, int winX, int winY) 
{ 
    LPPOINT point; 
    point->x = winX; 
    point->y = winY; 
    ClientToScreen((HWND) hwnd, point); 
    HDC dc = GetDC(NULL); 
    COLORREF colorPx = GetPixel(dc, point->x, point->y); 
    ReleaseDC(NULL, dc); 
    return colorPx; 
} 

所以,當我打電話直接導入ShowWindow()函數或調用api函數的函數庫nction(S),我有一個程序崩潰

有什麼辦法如何調試外部庫和它的結果嗎?

IM做錯了什麼?

非常感謝

+1

的* HWND *參數應該是類型的['IntPtr'](https://msdn.microsoft.com/en-us/library/system.intptr.aspx)。此外,您正在寫入未初始化的內存:「LPPOINT點;」沒有內存。這是一個指針。 – IInspectable

+0

VS - 啓用調試本機代碼複選框(_and不僅是我的代碼,類似於this_),打破所有異常。 [OllyDbg](http://www.ollydbg.de/),[IDA免費軟件](https://www.hex-rays.com/products/ida/support/download_freeware.shtml) – MrDywar

+0

[DWORD是32位。它也沒有簽名。](https://msdn.microsoft.com/en-us/library/windows/desktop/aa383751%28v=vs.85%29.aspx) – theB

回答

1

您有幾個調試問題的選項。

  1. 啓用在Visual Studio非託管代碼的調試。注意:VS 2010 Express不支持混合託管/非託管調試。 (Instructions
  2. 使用WinDbg。這將是我個人最喜歡的調試混合應用程序的選項。這是一個令人難以置信的強大工具。不可否認的是,學習曲線有點陡峭,但非常值得努力。
  3. 使用外部/第三方調試器,如OllyDbg。 (如所建議的通過MrDywar

的P /調用問題:

  1. 作爲IInspectable指出HWND應該傳遞給使用IntPtr非託管代碼。
  2. Windows API data types是明確定義的。 DWORD總是32位。另外,LONG(全部大寫)與long(小寫)不同。

C++的問題:

  1. 正如IInspectable提到的,LPPOINT永遠不會被初始化,所以當你打電話ClientToScreen()你所訪問未初始化堆棧垃圾爲指針,並分配值。要解決它,你可以:
    1. 分配的內存(你最喜歡的方案在這裏,LocalAllocGlobalAllocmalloccalloc
    2. 作出聲明POINT point;,使用point.x & point.y分配值,並且在函數調用中使用它。作爲&point
  2. 製作第一個參數的類型HWND。 API類型儘管最終是typedef,但它們帶有額外的含義。