将utf-16字符串传递给Windows函数 [英] Passing utf-16 string to a Windows function

查看:220
本文介绍了将utf-16字符串传递给Windows函数的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有一个名为some.dll的Windows dll,具有以下功能:

I have a Windows dll called some.dll with the following function:

void some_func(TCHAR* input_string)
{
...
}

some_func期望指向utf的指针-16编码的字符串。

some_func expects a pointer to utf-16 encoded string.

运行以下python代码:

Running this python code:

from ctypes import *

some_string = "disco duck"
param_to_some_func = c_wchar_p(some_string.encode('utf-16'))  #  here exception!

some_dll = ctypes.WinDLL(some.dll)
some_dll.some_func(param_to_some_func)

失败,但出现以下异常:期望使用Unicode字符串或整数地址而不是字节实例

fails with exception "unicode string or integer address expected instead of bytes instance"

ctypes和ctypes文档.wintypes非常薄,我还没有找到将python字符串转换为Windows范围的char并将其传递给函数的方法。

The documentation for ctypes and ctypes.wintypes is very thin, and I have not found a way to convert a python string to a Windows wide char and pass it to a function.

推荐答案

根据 [Python 3.Docs ]:内置类型-文本序列类型-str 强调是我的):


Python中的文本数据使用 str 对象或字符串。字符串是不可变的 Unicode代码点的顺序 >。

Textual data in Python is handled with str objects, or strings. Strings are immutable sequences of Unicode code points.

Win 上,它们是 UTF16 编码的。

因此, CTypes Python 之间的对应关系(也可以通过检查之间的差异看到):

So, the correspondence between CTypes and Python (also visible by checking the differences between):

  • [Python 3.Docs]: ctypes - Fundamental data types
  • [Python 2.Docs]: ctypes - Fundamental data types

╔═══════════════╦══════════════╦══════════════╗
║    CTypes     ║   Python 3   ║   Python 2   ║
╠═══════════════╬══════════════╬══════════════╣
║   c_char_p    ║    bytes     ║     str      ║
║   c_wchar_p   ║     str      ║   unicode    ║
╚═══════════════╩══════════════╩══════════════╝



示例:


  • Python 3

  • Python 3:


>>> import sys
>>> import ctypes as ct
>>>
>>> sys.version
'3.7.6 (tags/v3.7.6:43364a7ae0, Dec 19 2019, 00:42:30) [MSC v.1916 64 bit (AMD64)]'
>>>
>>> text_ascii = b"Dummy"
>>> text_unicode = "Dummy"
>>>
>>> ct.c_char_p(text_ascii)
c_char_p(2563882450144)
>>>
>>> ct.c_wchar_p(text_ascii)
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
TypeError: unicode string or integer address expected instead of bytes instance
>>>
>>> ct.c_char_p(text_unicode)
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
TypeError: bytes or integer address expected instead of str instance
>>>
>>> ct.c_wchar_p(text_unicode)
c_wchar_p(2563878400656)



  • Python 2 (请注意, str < => unicode 转换是自动执行的):

  • Python 2 (note that str <=> unicode conversions are performed automatically):


    >>> import sys
    >>> import ctypes as ct
    >>>
    >>> sys.version
    '2.7.17 (v2.7.17:c2f86d86e6, Oct 19 2019, 21:01:17) [MSC v.1500 64 bit (AMD64)]'
    >>>
    >>> text_ascii = "Dummy"
    >>> text_unicode = u"Dummy"
    >>>
    >>> ct.c_char_p(text_ascii)
    c_char_p('Dummy')
    >>>
    >>> ct.c_wchar_p(text_ascii)
    c_wchar_p(u'Dummy')
    >>>
    >>> ct.c_char_p(text_unicode)
    c_char_p('Dummy')
    >>>
    >>> ct.c_wchar_p(text_unicode)
    c_wchar_p(u'Dummy')
    



  • 返回您的情景:


    >>> import ctypes as ct
    >>>
    >>> some_string = "disco duck"
    >>>
    >>> enc_utf16 = some_string.encode("utf16")
    >>> enc_utf16
    b'\xff\xfed\x00i\x00s\x00c\x00o\x00 \x00d\x00u\x00c\x00k\x00'
    >>>
    >>> type(some_string), type(enc_utf16)
    (<class 'str'>, <class 'bytes'>)
    >>>
    >>> ct.c_wchar_p(some_string)  # This is the right way
    c_wchar_p(2508534214928)
    >>>
    >>> ct.c_wchar_p(enc_utf16)
    Traceback (most recent call last):
      File "<stdin>", line 1, in <module>
    TypeError: unicode string or integer address expected instead of bytes instance
    


    作为旁注, TUNI 在定义的 _UNICODE 上有所不同(这是 typedef )。检查 [MS.Docs]:通用-tchar.h 中的文本映射以获取更多详细信息。因此,根据 C 代码的编译标志, Python 代码也可能需要调整。

    As a side note, TCHAR varies (it's a typedef) on _UNICODE (not) being defined. Check [MS.Docs]: Generic-Text Mappings in tchar.h for more details. So, depending on the C code compilation flags, the Python code might also need adjustments.

    这篇关于将utf-16字符串传递给Windows函数的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

    查看全文
    登录 关闭
    扫码关注1秒登录
    发送“验证码”获取 | 15天全站免登陆