Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/python/298.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
从c+返回数据+;Python的动态链接库_Python_C++_Ctypes - Fatal编程技术网

从c+返回数据+;Python的动态链接库

从c+返回数据+;Python的动态链接库,python,c++,ctypes,Python,C++,Ctypes,我正在为3M文档扫描仪编程一个接口 我正在调用一个名为MMMReader\u GetData MMMReaderErrorCode MMMReader_GetData(MMMReaderDataType aDataType,void* DataPtr,int* aDataLen); 说明: 从文档中读取数据项后,可以通过 这个API。aDataPtr参数中提供的缓冲区将 用数据写入,并将aDataLen更新为 数据 问题是如何创建一个void*DataPrt,以及如何从中获取数据 我试过: f

我正在为3M文档扫描仪编程一个接口

我正在调用一个名为
MMMReader\u GetData

MMMReaderErrorCode MMMReader_GetData(MMMReaderDataType aDataType,void* DataPtr,int* aDataLen);
说明:

从文档中读取数据项后,可以通过 这个API。aDataPtr参数中提供的缓冲区将 用数据写入,并将aDataLen更新为 数据

问题是如何创建一个
void*DataPrt
,以及如何从中获取数据

我试过:

from ctypes import *
lib=cdll.LoadLibrary('MMMReaderHighLevelAPI.dll')
CD_CODELINE = 0
aDataLen = c_int()
aDataPtr = c_void_p()
index= c_int(0)

r = lib.MMMReader_GetData(CD_CODELINE,byref(aDataPtr),byref(aDataLen),index)

aDataLen
始终返回一个值,但
aDataPtr
返回
None

您的代码有几个问题:

  • 您需要分配
    aDataPtr
    指向的缓冲区
  • 您需要在
    aDataLen
    中传递缓冲区长度。根据[1],如果缓冲区不够大,
    MMMReader\u GetData
    将根据需要重新分配它
  • 您应该直接传递
    aDataPtr
    ,而不是
    byref
  • 根据您提供的
    MMMReader\u GetData
    的方法描述符,您正在向方法传递一个额外的参数(index参数)
  • 请尝试以下操作:

    import ctypes
    
    lib = ctypes.cdll.LoadLibrary('MMMReaderHighLevelAPI.dll')
    
    CD_CODELINE = 0
    aDataLen = ctypes.c_int(1024)
    aDataPtr = ctypes.create_string_buffer(aDataLen.value)
    
    err = lib.MMMReader_GetData(CD_CODELINE, aDataPtr, ctype.byref(aDataLen))
    
    然后可以将缓冲区的内容作为常规字符数组读取。实际长度将在
    aDataLen
    中返回给您


    [1] 3M页的读者程序员指南:

    您的代码有几个问题:

  • 您需要分配
    aDataPtr
    指向的缓冲区
  • 您需要在
    aDataLen
    中传递缓冲区长度。根据[1],如果缓冲区不够大,
    MMMReader\u GetData
    将根据需要重新分配它
  • 您应该直接传递
    aDataPtr
    ,而不是
    byref
  • 根据您提供的
    MMMReader\u GetData
    的方法描述符,您正在向方法传递一个额外的参数(index参数)
  • 请尝试以下操作:

    import ctypes
    
    lib = ctypes.cdll.LoadLibrary('MMMReaderHighLevelAPI.dll')
    
    CD_CODELINE = 0
    aDataLen = ctypes.c_int(1024)
    aDataPtr = ctypes.create_string_buffer(aDataLen.value)
    
    err = lib.MMMReader_GetData(CD_CODELINE, aDataPtr, ctype.byref(aDataLen))
    
    然后可以将缓冲区的内容作为常规字符数组读取。实际长度将在
    aDataLen
    中返回给您


    [1] 3M页的读者程序员指南:

    您需要做的是分配一个“缓冲区”。缓冲区的地址将作为void*参数传递,以字节为单位的缓冲区大小将作为
    aDataLen
    参数传递。然后函数将把它的数据放在你给它的缓冲区中,然后你可以从缓冲区中读取数据


    <>在C或C++中,你会使用<代码> Malc C >代码>或类似的东西来创建缓冲区。当使用
    ctypes
    时,您可以使用创建一个特定长度的缓冲区,然后将缓冲区和长度传递给函数。然后,一旦函数填充了数据,您就可以从创建的缓冲区中读取数据,该缓冲区的工作方式类似于一个字符列表,分别为
    []
    len()

    您需要做的是分配一个“缓冲区”。缓冲区的地址将作为void*参数传递,以字节为单位的缓冲区大小将作为
    aDataLen
    参数传递。然后函数将把它的数据放在你给它的缓冲区中,然后你可以从缓冲区中读取数据


    <>在C或C++中,你会使用<代码> Malc C >代码>或类似的东西来创建缓冲区。当使用
    ctypes
    时,您可以使用创建一个特定长度的缓冲区,然后将缓冲区和长度传递给函数。然后,一旦函数填充了数据,您就可以从创建的缓冲区中读取数据,该缓冲区的工作方式类似于一个字符列表,分别为
    []
    len()

    对于
    ctypes
    ,最好定义参数类型和返回值,以便更好地进行错误检查,并且声明指针类型在64位系统上尤其重要

    from ctypes import *
    
    MMMReaderErrorCode = c_int  # Set to an appropriate type
    MMMReaderDataType = c_int   # ditto...
    
    lib = CDLL('MMMReaderHighLevelAPI')
    lib.MMMReader_GetData.argtypes = MMMReaderDataType,c_void_p,POINTER(c_int)
    lib.MMMReader_GetData.restype = MMMReaderErrorCode
    
    CD_CODELINE = 0
    
    # Make sure to pass in the original buffer size.
    # Assumption: the API should update it on return with the actual size used (or needed)
    # and will probably return an error code if the buffer is not large enough.
    aDataLen = c_int(256)
    
    # Allocate a writable buffer of the correct size.
    aDataPtr = create_string_buffer(aDataLen.value)
    
    # aDataPtr is already a pointer, so no need to pass it by reference,
    # but aDataLen is a reference so the value can be updated.
    r = lib.MMMReader_GetData(CD_CODELINE,aDataPtr,byref(aDataLen))
    
    返回时,您可以通过字符串切片仅访问缓冲区的返回部分,例如:

    >>> from ctypes import *
    >>> aDataLen = c_int(10)
    >>> aDataPtr = create_string_buffer(aDataLen.value)
    >>> aDataPtr.raw
    '\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00'
    >>> aDataLen.value = 5        # Value gets updated
    >>> aDataPtr[:aDataLen.value] # Get the valid portion of buffer
    '\x00\x00\x00\x00\x00'
    

    使用
    ctypes
    ,最好定义参数类型和返回值,以便更好地进行错误检查,并且在64位系统上声明指针类型尤其重要

    from ctypes import *
    
    MMMReaderErrorCode = c_int  # Set to an appropriate type
    MMMReaderDataType = c_int   # ditto...
    
    lib = CDLL('MMMReaderHighLevelAPI')
    lib.MMMReader_GetData.argtypes = MMMReaderDataType,c_void_p,POINTER(c_int)
    lib.MMMReader_GetData.restype = MMMReaderErrorCode
    
    CD_CODELINE = 0
    
    # Make sure to pass in the original buffer size.
    # Assumption: the API should update it on return with the actual size used (or needed)
    # and will probably return an error code if the buffer is not large enough.
    aDataLen = c_int(256)
    
    # Allocate a writable buffer of the correct size.
    aDataPtr = create_string_buffer(aDataLen.value)
    
    # aDataPtr is already a pointer, so no need to pass it by reference,
    # but aDataLen is a reference so the value can be updated.
    r = lib.MMMReader_GetData(CD_CODELINE,aDataPtr,byref(aDataLen))
    
    返回时,您可以通过字符串切片仅访问缓冲区的返回部分,例如:

    >>> from ctypes import *
    >>> aDataLen = c_int(10)
    >>> aDataPtr = create_string_buffer(aDataLen.value)
    >>> aDataPtr.raw
    '\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00'
    >>> aDataLen.value = 5        # Value gets updated
    >>> aDataPtr[:aDataLen.value] # Get the valid portion of buffer
    '\x00\x00\x00\x00\x00'