【问题标题】:python unmanaged dll call, fails on win32 FindWindow api with Access Violationpython非托管dll调用,在win32 FindWindow api上因访问冲突而失败
【发布时间】:2011-09-22 20:41:42
【问题描述】:

我在 DLL 中有以下最基本的功能

#define INTELHOOK_API extern "C" __declspec(dllexport)    
INTELHOOK_API BOOL testFunc(void) {
    BOOL success = false;
    HWND parent = NULL;

    parent = FindWindow("Arium.SourcePont", NULL);
    if (parent != NULL) {
        success = true;
    }
    return success;
}

如果我从 DLL 中的主函数调用它,它工作正常。如果我从 python 调用它,我会得到以下信息:

WindowsError: exception: access violation reading 0x00439508

我的 python 脚本如下所示:

from ctypes import *
dll = cdll.hook
print dll.testFunc()

我在win7上运行,64位,但dll和python都是32位:

c:\Projects\hg\hooklib>dumpbin /headers hook.dll
Microsoft (R) COFF/PE Dumper Version 9.00.21022.08
Copyright (C) Microsoft Corporation.  All rights reserved.

Dump of file hook.dll
PE signature found

File Type: EXECUTABLE IMAGE
FILE HEADER VALUES
             14C machine (x86)

'

打印系统版本 2.7.2(默认,2011 年 6 月 12 日,15:08:59)[MSC v.1500 32 位(英特尔)]

我附加了一个调试器,但似乎无法解决它。

'python.exe': Loaded 'C:\Python27\python.exe'
'python.exe': Loaded 'C:\Windows\SysWOW64\ntdll.dll', Symbols loaded (source information stripped).
'python.exe': Loaded 'C:\Windows\SysWOW64\kernel32.dll', Symbols loaded (source information stripped).
'python.exe': Loaded 'C:\Windows\SysWOW64\KernelBase.dll', Symbols loaded (source information stripped).
'python.exe': Loaded 'C:\Windows\SysWOW64\python27.dll'
'python.exe': Loaded 'C:\Windows\SysWOW64\user32.dll', Symbols loaded (source information stripped).
'python.exe': Loaded 'C:\Windows\SysWOW64\gdi32.dll', Symbols loaded (source information stripped).
'python.exe': Loaded 'C:\Windows\SysWOW64\lpk.dll', Symbols loaded (source information stripped).
'python.exe': Loaded 'C:\Windows\SysWOW64\usp10.dll', Symbols loaded (source information stripped).
'python.exe': Loaded 'C:\Windows\SysWOW64\msvcrt.dll', Symbols loaded (source information stripped).
'python.exe': Loaded 'C:\Windows\SysWOW64\advapi32.dll', Symbols loaded (source information stripped).
'python.exe': Loaded 'C:\Windows\SysWOW64\sechost.dll', Symbols loaded (source information stripped).
'python.exe': Loaded 'C:\Windows\SysWOW64\rpcrt4.dll', Symbols loaded (source information stripped).
'python.exe': Loaded 'C:\Windows\SysWOW64\sspicli.dll', Symbols loaded (source information stripped).
'python.exe': Loaded 'C:\Windows\SysWOW64\cryptbase.dll', Symbols loaded (source information stripped).
'python.exe': Loaded 'C:\Windows\SysWOW64\shell32.dll', Symbols loaded (source information stripped).
'python.exe': Loaded 'C:\Windows\SysWOW64\shlwapi.dll', Symbols loaded (source information stripped).
'python.exe': Loaded 'C:\Windows\winsxs\x86_microsoft.vc90.crt_1fc8b3b9a1e18e3b_9.0.30729.6161_none_50934f2ebcb7eb57\msvcr90.dll', Symbols loaded (source information stripped).
'python.exe': Loaded 'C:\Windows\SysWOW64\imm32.dll', Symbols loaded (source information stripped).
'python.exe': Loaded 'C:\Windows\SysWOW64\msctf.dll', Symbols loaded (source information stripped).
'python.exe': Loaded 'C:\Windows\SysWOW64\PGPmapih.dll'
'python.exe': Loaded 'C:\Python27\DLLs\_ctypes.pyd'
'python.exe': Loaded 'C:\Windows\SysWOW64\ole32.dll', Symbols loaded (source information stripped).
'python.exe': Loaded 'C:\Windows\SysWOW64\oleaut32.dll', Symbols loaded (source information stripped).
'python.exe': Loaded 'C:\Projects\hg\hooklib\hook.dll', Symbols loaded.
The thread 'Win32 Thread' (0x10b0) has exited with code 0 (0x0).
First-chance exception at 0x01d428ae (hook.dll) in python.exe: 0xC0000005: Access violation reading location 0x00439508.
The program '[3836] python.exe: Native' has exited with code 1 (0x1).

当我通过 JNA 使用 Java 访问函数时,也会发生同样的情况。 鉴于该函数在从 dll 中的 main 调用时有效,这让我相信这是一些访问限制,但这没有意义。我不能成为第一个在 dll 中间接调用 win32 函数的人...

提前感谢您抽出宝贵时间阅读所有内容!

干杯

【问题讨论】:

    标签: python dll unmanaged access-violation


    【解决方案1】:

    不管怎样,这对我来说在 32 位 Windows XP 中运行良好,使用 Python 3.2.1 和 2.7.2,使用 i686-w64-mingw32-g++.exe 版本 4.5.3 编译:

    c/test.cpp:

    #include <windows.h>
    
    #define INTELHOOK_API extern "C" __declspec(dllexport)
    INTELHOOK_API BOOL test(void) {
        BOOL success = FALSE;
        HWND parent = NULL;
    
        parent = FindWindow("notepad", NULL);
        if (parent != NULL) {
            success = TRUE;
        }
        return success;
    }
    
    // g++ test.cpp -o test.dll -shared
    

    test.py:

    import ctypes
    dll = ctypes.cdll.LoadLibrary('c/test.dll')
    print(dll.test())
    

    如果记事本窗口打开,则打印 1,否则打印 0。

    【讨论】:

      【解决方案2】:

      @eryksun 谢谢你的尝试。您的回答使我找到了解决方案。

      我在编译时缺少与 GCC 的 -shared(即 /LD)等效的 MSVC。

      我最初从 C 语言开发和测试 DLL 函数,然后添加了导出但忘记添加 /LD 选项。

      我会将这个问题标记为已解决,但我仍然想知道如果我没有正确的 DllMain,为什么它会导致访问冲突。

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2011-09-24
        • 2012-07-05
        • 2021-10-27
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2011-09-21
        相关资源
        最近更新 更多