简体   繁体   English

使用 VS 2010 调试导入的 dll

[英]Debug an imported dll with VS 2010

I have a problem while I trying to call WinAPI functions from C# code.我在尝试从 C# 代码调用 WinAPI 函数时遇到问题。 I have lots of imports, many of them works fine, but some of them not and leading to unexpected break main program, without any message, exception type, nothing, just fell down all its windows and exit.我有很多导入,其中许多工作正常,但其中一些没有并导致意外中断主程序,没有任何消息,异常类型,什么都没有,只是掉下所有窗口并退出。

I have two ways in code: via my developed library, where is more of winapi calls and I'm lazy to code specific structures, pointers, etc, and direct import from user32.dll, like this:我在代码中有两种方法:通过我开发的库,那里有更多的 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; ...

As I said, many of this calls works perfectly, but have problem of last two of them: ShowWindow() and PixelColor() with following code:正如我所说,其中许多调用都可以完美运行,但最后两个调用存在问题: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;
}

So, while I try to call directly imported ShowWindow() function, or library which calls api function(s), I got a program crash因此,当我尝试调用直接导入的 ShowWindow() 函数或调用 api 函数的库时,我遇到了程序崩溃

Is there any way how to debug external libraries and its results?有什么方法可以调试外部库及其结果吗?

What I¨m doing wrong?我做错了什么?

Thanks a lot非常感谢

You have several options for debugging issues.您有多种调试问题的选项。

  1. Enable unmanaged code debugging in Visual Studio.在 Visual Studio 中启用非托管代码调试。 Note: VS 2010 Express does not support mixed managed/unmanaged debugging.注意:VS 2010 Express 不支持混合托管/非托管调试。 ( Instructions ) ( 说明)
  2. Use WinDbg .使用WinDbg This would be my personal favorite option for debugging mixed applications.这将是我个人最喜欢的调试混合应用程序的选项。 It is an incredibly powerful tool.这是一个非常强大的工具。 Admittedly the learning curve is a little steep, but it's well worth the effort.诚然,学习曲线有点陡峭,但值得付出努力。
  3. Use an external/third party debugger like OllyDbg.使用像 OllyDbg 这样的外部/第三方调试器。 (As suggested by MrDywar ) (根据MrDywar 的建议)

The P/Invoke problems: P/Invoke 问题:

  1. As IInspectable pointed out HWND should be passed to unmanaged code using IntPtr .正如IInspectable指出的那样, HWND应该使用IntPtr传递给非托管代码。
  2. Windows API data types are well defined. Windows API 数据类型定义明确。 DWORD is always 32 bit. DWORD始终为 32 位。 Also, LONG (all caps) is not the same as long (lower case).此外, LONG (全部大写)与long (小写)不同。

The C++ Problems: C++ 问题:

  1. As mentioned by IInspectable , the LPPOINT is never initialized, so when you call ClientToScreen() you're accessing uninitialized stack garbage as a pointer, and assigning values.正如IInspectable所提到的, LPPOINT从未初始化,因此当您调用ClientToScreen()您将未初始化的堆栈垃圾作为指针访问并分配值。 To Fix it you could:要修复它,您可以:
    1. Allocate the memory (your favorite scheme here, LocalAlloc , GlobalAlloc , malloc , calloc .分配内存(你最喜欢的方案, LocalAllocGlobalAllocmalloccalloc
    2. Make the declaration POINT point;使申报POINT point; , assign values using point.x & point.y , and use it in the function call as &point . ,使用point.x & point.y分配值,并在函数调用中使用它作为&point
  2. Make the first parameter's type HWND .使第一个参数的类型为HWND The API types, even though they are ultimately typedefs, carry extra meaning with them. API 类型,即使它们最终是 typedef,也带有额外的含义。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM