Python 3.x 将utf-16字符串传递给Windows函数

Python 3.x 将utf-16字符串传递给Windows函数,python-3.x,ctypes,pywin32,Python 3.x,Ctypes,Pywin32,我有一个名为some.dll的Windows dll,具有以下功能: void some_func(TCHAR* input_string) { ... } 某些函数需要指向utf-16编码字符串的指针 运行以下python代码: from ctypes import * some_string = "disco duck" param_to_some_func = c_wchar_p(some_string.encode('utf-16')) # here exception! so

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

void some_func(TCHAR* input_string)
{
...
}
某些函数需要指向utf-16编码字符串的指针

运行以下python代码:

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字符串或整数地址,而不是字节实例”

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

根据(emphasis是我的):

Python中的文本数据是用对象或字符串处理的。字符串是Unicode代码点不可变的

在Win上,它们是UTF16编码的

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


例如:

  • Python3

    导入系统 >>>将ctypes导入为ct >>> >>>sys.version “3.7.6(tags/v3.7.6:43364a7ae0,2019年12月19日,00:42:30)[MSC v.1916 64位(AMD64)]” >>> >>>文本\u ascii=b“虚拟” >>>text_unicode=“Dummy” >>> >>>ct.c_char_p(文本ascii) c_char_p(2563882450144) >>> >>>ct.c_wchar_p(文本\u ascii) 回溯(最近一次呼叫最后一次): 文件“”,第1行,在 TypeError:需要unicode字符串或整数地址,而不是字节实例 >>> >>>ct.c_char_p(文本\u unicode) 回溯(最近一次呼叫最后一次): 文件“”,第1行,在 TypeError:需要字节或整数地址,而不是str实例 >>> >>>ct.c_wchar_p(文本\u unicode) c_wchar_p(2563878400656)
  • Python2(请注意,str unicode转换是自动执行的):

    导入系统 >>>将ctypes导入为ct >>> >>>sys.version “2.7.17(v2.7.17:c2f86d86e6,2019年10月19日,21:01:17)[MSC v.1500 64位(AMD64)]” >>> >>>text_ascii=“Dummy” >>>text_unicode=u“Dummy” >>> >>>ct.c_char_p(文本ascii) c_char_p('Dummy')) >>> >>>ct.c_wchar_p(文本\u ascii) c_wchar_p(u'Dummy') >>> >>>ct.c_char_p(文本\u unicode) c_char_p('Dummy')) >>> >>>ct.c_wchar_p(文本\u unicode) c_wchar_p(u'Dummy')
回到你的处境:

>将ctypes作为ct导入
>>>
>>>一些\u string=“迪斯科鸭子”
>>>
>>>enc_utf16=一些字符串。编码(“utf16”)
>>>附件utf16
b'\xff\xfed\x00i\x00s\x00c\x00o\x00\x00d\x00u\x00c\x00k\x00'
>>>
>>>类型(某些字符串),类型(enc_utf16)
(, )
>>>
>>>ct.c_wchar_p(一些字符串)#这是正确的方法
c_wchar_p(2508534214928)
>>>
>>>ct.c_wchar_p(附件utf16)
回溯(最近一次呼叫最后一次):
文件“”,第1行,在
TypeError:需要unicode字符串或整数地址,而不是字节实例
作为旁注,TCHAR在被定义的UNICODE上有所不同(它是一个typedef)。查看更多详细信息。因此,根据C代码编译标志,Python代码可能也需要调整

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