OSError:异常:在创建库实例后调用任何函数时发生访问冲突读|写

问题描述 投票:0回答:2

我正在尝试使用 Python 使用 SecuGen 指纹扫描仪,我使用的 SDK 库是

sgfplib.dll
。我有一个 C++ 程序,它使用这个 DLL 并使用 C++ 和相同的 DLL 访问硬件。 我还可以使用 Windows 生物识别框架 (
winbio.dll
)、Python 和 ctypes 访问设备,但该框架没有我需要的功能。

问题是,使用

sgfplib.dll
,创建主库对象后,我可以很好地获得 dll 的句柄,但每当我尝试调用任何其他函数时,我都会得到
OSError: exception: access violation reading|writing 0x###########

我已经搜索了该网站和谷歌寻找类似的错误,但似乎没有什么接近我的问题。我在我的

system32
文件夹中找到了 DLL,我也尝试将它们放入脚本目录中,但没有任何运气

如果我更改 devname 或调用 diff 函数,错误中的地址确实会更改。

任何人都可以指出我正确的方向或提供有关此类错误的更多信息吗?

这是一个最小的可重现示例:

import ctypes
from ctypes import wintypes

lib = ctypes.WinDLL(r"..\pathToTheDLLsDir\sgfplib.dll")
session_handle = ctypes.c_uint32()
devname = ctypes.wintypes.DWORD()
devname = "SG_DEV_FDU05" # 5

err = lib.SGFPM_Create(ctypes.byref(session_handle)) # create an SGFPM object and 
print('CREATE', err) # 0                             # return a handle to the object

err = lib.SGFPM_Init(ctypes.byref(session_handle), devname) # OSError: exception: access 
print('INIT', err)                                          # violation reading 0x00000000AFE3FB10
python dll ctypes fingerprint
2个回答
0
投票

清单 [Python.Docs]:ctypes - Python 的外部函数库

这个错误很常见,我已经在 SO 上回答了一堆问题(关于同一主题)。
代码充满了Undefined Behavior。最常见的是 [SO]:通过 ctypes 从 Python 调用的 C 函数返回不正确的值(@CristiFati 的答案),在调用函数时遇到。

找到 SecuGen 参考文献(不幸的是没有官方参考文献):

我准备了一个虚拟示例(下载了一个.dll用于测试目的,但由于我没有设备而无法完全测试)。

code00.py

#!/usr/bin/env python

import ctypes as cts
import ctypes.wintypes as wts
import sys


HSGFPM = cts.c_void_p

DLL_NAME = "./sgfplib.{:s}".format("dll" if sys.platform[:3].lower() == "win" else "so")

# @TODO - cfati: Can add all constants here
SG_DEV_FDU04 = 0x05
SG_DEV_FDU05 = 0x06


def is_error(error_code):
    # @TODO - cfati: Assume functions return 0 on success
    if error_code != 0:
        return True
    return False


def main(*argv):
    dll = cts.WinDLL(DLL_NAME)
    SGFPM_Create = dll.SGFPM_Create
    SGFPM_Create.argtypes = (cts.POINTER(HSGFPM),)
    SGFPM_Create.restype = wts.DWORD
    SGFPM_Init = dll.SGFPM_Init
    SGFPM_Init.argtypes = (HSGFPM, wts.DWORD)
    SGFPM_Init.restype = wts.DWORD
    SGFPM_Terminate = dll.SGFPM_Terminate
    SGFPM_Terminate.argtypes = (HSGFPM,)
    SGFPM_Terminate.restype = wts.DWORD

    handle = HSGFPM()

    res = SGFPM_Create(cts.byref(handle))
    if is_error(res):
        print("Error SGFPM_Create: {:d}".format(res))
        return

    dev = SG_DEV_FDU04

    res = SGFPM_Init(handle, dev)
    if is_error(res):
        print("Error SGFPM_Init: {:d}".format(res))
        SGFPM_Terminate(handle)
        return

    # Do your thing

    SGFPM_Terminate(handle)


if __name__ == "__main__":
    print("Python {:s} {:03d}bit on {:s}\n".format(" ".join(elem.strip() for elem in sys.version.split("\n")),
                                                   64 if sys.maxsize > 0x100000000 else 32, sys.platform))
    rc = main(*sys.argv[1:])
    print("\nDone.\n")
    sys.exit(rc)

-1
投票

结果我需要通过

GetModuleHandleA
库中的
kernel32
函数获取句柄,然后将其传递给
SGFPM_Create()
函数:

from ctypes import *

lib = ctypes.WinDLL(r"..\pathToTheDLLsDir\sgfplib.dll")
session_handle = windll.kernel32.GetModuleHandleA
lib.SGFPM_Create(ctypes.byref(pointer))

之后我就可以使用

sgfplib.dll
中的所有功能了。

© www.soinside.com 2019 - 2024. All rights reserved.