2010-09-19 70 views
6

我正在使用现有模块,此时提供了一个C++接口并对字符串执行了一些操作。Python:将unicode字符串传递给C++模块

我需要使用Unicode字符串和模块遗憾的是没有为一个Unicode接口的支持,所以我写了一个额外的功能添加到界面:

void SomeUnicodeFunction(const wchar_t* string) 

然而,当我尝试使用Python中下面的代码:

SomeModule.SomeUnicodeFunction(ctypes.c_wchar_p(unicode_string)) 

我得到这个错误:

ArgumentError: Python argument types in 
    SomeModule.SomeUnicodeFunction(SomeModule, c_wchar_p) 
did not match C++ signature: 
    SomeUnicodeFunction(... {lvalue}, wchar_t const*) 

(名称已更改)。

我试着将C++模块中的wchar_t更改为Py_UNICODE,但没有成功。我该如何解决这个问题?

+0

Boost.python不会自动识别ctypes类型,据我所知,但它应该可能只适用于内置的unicode字符串。如果您尝试调用'SomeModule.SomeUnicodeFunction(unicode_string)',会发生什么? – Doug 2010-09-19 02:39:42

+0

@Dough:同样的错误,但使用“unicode”而不是“c_wchar_p”作为Python参数类型。 – 2010-09-19 03:48:51

+0

@Matthew,w /或w/o不用'c_wchar_p'强制转换,看起来它应该工作,除了'const'(这在ctypes'文档中没有提及) - 如果你省略'在C代码中的const? (注意''ctypes'没有直接的C++支持:当然,函数必须从C++的角度来看是'extern C')。 – 2010-09-19 04:54:27

回答

2

对于Linux,你不必改变你的API,只是做:

SomeModule.SomeFunction(str(s.encode('utf-8'))) 

在Windows所有Unicode API的使用UTF-16 LE(小端),所以你必须这样进行编码:

SomeModule.SomeFunctionW(str(s.encode('utf-16-le'))) 

提提:8,16或32位:wchar_t的可以在不同平台上具有不同的尺寸。

+0

我正在使用Linux,实际上。我已经更新了我自己对这个问题的答案。 – 2010-09-20 13:01:37

2

发现一个黑客以解决此问题:

SomeModule.SomeUnicodeFunction(str(s.encode('utf-8'))) 

看来,我的目的是工作的罚款至今。

更新:实际上,使用UTF-8意味着我避免了任何SomeUnicodeFunction的需要,并且可以使用标准的SomeFunction而不专门用于unicode。每天学习新的东西我猜:)。