使用VS 2010调试导入的dll

霍里根

尝试从C#代码调用WinAPI函数时遇到问题。我有很多导入,其中很多可以正常工作,但是其中一些导入不正常,并导致意外中断主程序,没有任何消息,异常类型,什么都没有,只是掉下了所有窗口并退出。

我有两种编码方式:通过我开发的库,有更多的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函数的库时,程序崩溃

有什么方法可以调试外部库及其结果吗?

我做错了什么?

非常感谢

您有几个调试问题的选项。

  1. 在Visual Studio中启用非托管代码调试。注意:VS 2010 Express不支持混合托管/非托管调试。说明
  2. 使用WinDbg对于调试混合应用程序,这将是我个人最喜欢的选项。这是一个非常强大的工具。诚然,学习曲线有些陡峭,但是值得付出努力。
  3. 使用外部/第三方调试器,例如OllyDbg。(如MrDywar所建议

P /调用问题:

  1. 正如IInspectable指出的,HWND应使用传递给非托管代码IntPtr
  2. Windows API数据类型定义明确。DWORD始终为32位。另外,LONG(所有大写字母)与long(小写字母)不同。

C ++问题:

  1. IInspectable所述LPPOINT,永不初始化,因此在调用时,ClientToScreen()您将访问未初始化的堆栈垃圾作为指针,并分配值。要解决此问题,您可以:
    1. 分配的内存(你最喜欢的方案在这里LocalAllocGlobalAllocmalloccalloc
    2. 进行声明POINT point;,使用point.x赋值point.y,并在函数调用中使用as &point
  2. 设置第一个参数的类型HWND即使它们最终是typedef,API类型也带有额外的含义。

本文收集自互联网,转载请注明来源。

如有侵权,请联系 [email protected] 删除。

编辑于
0

我来说两句

0 条评论
登录 后参与评论

相关文章