2015-09-11 3 views
2

У меня проблема при попытке вызвать функции WinAPI из кода C#. У меня много импорта, многие из них прекрасно работают, но некоторые из них не приводят к неожиданным прерываниям основной программы, без какого-либо сообщения, типа исключения, ничего, просто упали все его окна и выходят.Отладка импортированной dll с VS 2010

У меня есть два пути в коде: через мою развитом библиотеку, где есть больше 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 fu nction (s), я получил программный сбой

Есть ли способ отладки внешних библиотек и его результатов?

Что я делаю неправильно?

Большое спасибо

+1

Параметры * hwnd * должны иметь тип ['IntPtr'] (https://msdn.microsoft.com/en-us/library/system.intptr.aspx). Кроме того, вы пишете в неинициализированную память: нет памяти для точки LPPOINT; '. Это указатель. – IInspectable

+0

VS - включить встроенный код отладки (_ и не только мой код, что-то вроде этого_), сломать все исключения. [OllyDbg] (http://www.ollydbg.de/), [IDA Freeware] (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/Invoke проблемы:

  1. Как IInspectable отметил HWND должны быть переданы в неуправляемый код, используя IntPtr.
  2. Windows API data types четко определены. DWORD всегда 32 бит. Кроме того, LONG (все колпачки) - это не то же самое, что и long (нижний регистр).

Проблемы C++:

  1. Как отметил IInspectable, то LPPOINT никогда не инициализируется, поэтому при вызове ClientToScreen() вы обращаетесь неинициализированный стека мусора в качестве указателя и присвоения значений. Для того, чтобы исправить это вы можете:
    1. Выделяют память (понравившуюся схему здесь, LocalAlloc, GlobalAlloc, malloc, calloc
    2. сделать заявление POINT point;, присвоить значения с помощью point.x & point.y, и использовать его в вызове функции. как &point.
  2. Сделать первый параметр параметра HWND. Типы API, даже если они в конечном итоге являются typedefs, несут в себе дополнительный смысл.
Смежные вопросы