Ctypes-String指针

时间:2018-02-28 12:49:16

标签: python pointers dll ctypes

这个python代码调用一个dll(在LabVIEW中创建),它返回作为参数传递的字符串的大小。 每次我尝试传递不同大小的字符串时,它返回的大小为" 1"。 我尝试用不同的编程语言(如C,LabVIEW)调用dll,它工作得很好。

下载dll文件的链接:https://drive.google.com/open?id=1pnYI6-SfUY3Cn6EeD4mWUO6dlEBH3DmN

    import ctypes
    from ctypes import windll, cdll,\
        c_wchar, c_size_t, c_ulonglong, c_wchar_p, c_void_p,\
        sizeof,\
        WinError
    try:
        dllhandle = ctypes.CDLL("Strlen.dll")
        print("Library Loaded")
    except Exception as e:
        print("Can't open DLL:",e)
    dllhandle.Strlen.argtypes = [ctypes.c_wchar_p]
    dllhandle.Strlen.restype = ctypes.c_int32
    data = "Hello"
    data_ptr = ctypes.c_wchar_p(data)
    print("Data Pointer:",data_ptr)
    length = dllhandle.Strlen(data_ptr)
    print("Data:",data)
    print("String Length:",length)

任何人都可以帮我解决这个问题吗?。提前谢谢。

1 个答案:

答案 0 :(得分:0)

备注

我的猜测是正确的:该函数需要char * 8位),而wchar\t * 16位

测试代码( code.py ):

#!/usr/bin/env python3

import sys
from ctypes import CDLL,\
    c_int, c_char_p, c_wchar_p


WORDS = [
    "",
    "a",
    "q z",
    "asd\n",
    "12345",
    "qwertyuiop",
]


if __name__ == "__main__":
    print("Python {:s} on {:s}\n".format(sys.version, sys.platform))
    strlen_dll = CDLL("Strlen")
    strlen_func = strlen_dll.Strlen
    strlen_func.restype = c_int
    for word in WORDS:
        print("{:s}:\n    len: {:d}".format(repr(word), len(word)))
        strlen_func.argtypes = [c_char_p]
        print("    Strlen.Strlen(c_char_p): {:d}".format(strlen_func(word.encode())))
        strlen_func.argtypes = [c_wchar_p]
        print("    Strlen.Strlen(c_wchar_p): {:d}".format(strlen_func(word)))

<强>输出

(py35x64_test) E:\Work\Dev\StackOverflow\q049030000>"e:\Work\Dev\VEnvs\py35x64_test\Scripts\python.exe" code.py
Python 3.5.4 (v3.5.4:3f56838, Aug  8 2017, 02:17:05) [MSC v.1900 64 bit (AMD64)] on win32

'':
    len: 0
    Strlen.Strlen(c_char_p): 0
    Strlen.Strlen(c_wchar_p): 0
'a':
    len: 1
    Strlen.Strlen(c_char_p): 1
    Strlen.Strlen(c_wchar_p): 1
'q z':
    len: 3
    Strlen.Strlen(c_char_p): 3
    Strlen.Strlen(c_wchar_p): 1
'asd\n':
    len: 4
    Strlen.Strlen(c_char_p): 4
    Strlen.Strlen(c_wchar_p): 1
'12345':
    len: 5
    Strlen.Strlen(c_char_p): 5
    Strlen.Strlen(c_wchar_p): 1
'qwertyuiop':
    len: 10
    Strlen.Strlen(c_char_p): 10
    Strlen.Strlen(c_wchar_p): 1

<强>解释

    使用宽字符时, Win 使用
  • wchar_t (或unsigned short)。根据{{​​3}}

      

    Windows表示使用UTF-16编码的Unicode字符,其中每个字符都编码为16位值。

  • UTF-16 上搜索 Google 会产生大量结果,以下是其中几项:
  • 我们以字符 A (hex 0x41 )为例。由于它是一个简单的 ASCII ,它将表示为 wchar_t ,如:
    • 0x00 - 这个字节不是必需的,也没有代码页,你可以像填充字节那样查看它
    • 0x41 - 值本身
  • 如图所示, wchar_t 的1 st 字节为 0 ,与 NULL 相同>字符终结符([Wikipedia]: Code page)。所以,在不知道的情况下,你传递的是包含这些字符的字符串,当函数遇到1 st 时,它会停止
  • 但为什么它会在字符串中返回 1 (而不是 0 作为1 st 宽字符 0x00 开头?这是因为[Wikipedia]: Null-terminated string(以及 Intel CPU OS es在其上运行的事实 小端 )。您还应该检查[Wikipedia]: Endianness endianness 相关部分)