cppyy.ll.cast 无法转换 char*
假设我们有一个来自某个外部库的名为 chr_ptr 的 char* 。
我尝试使用 cppyy.ll.cast["char*"](chr_ptr) 将此指针强制转换为 char*
预期:cppyy.LowLevelView >
实际:str
其他数据类型都可以正常工作,这个问题只发生在 char(又名 int8_t)。转换指针(比方说)int16_t 就可以了。
import cppyy
import cppyy.ll
if not hasattr(cppyy.gbl, "get_char_pointer"):
cppyy.cppdef("""
void* get_char_pointer()
{
char a = 1;
return &a;
}
""")
if not hasattr(cppyy.gbl, "get_uint16_t_pointer"):
cppyy.cppdef("""
void* get_uint16_t_pointer()
{
uint16_t a = 1;
return &a;
}
""")
if not hasattr(cppyy.gbl, "print_address"):
cppyy.cppdef("""
void print_address(void* p)
{
std::cout << "address is: " << p << std::endl;
}
""")
char_ptr = cppyy.gbl.get_char_pointer()
uint16t_ptr = cppyy.gbl.get_uint16_t_pointer()
cppyy.gbl.print_address(char_ptr)
cppyy.gbl.print_address(uint16t_ptr)
casted_char_ptr = cppyy.ll.cast["char*"](char_ptr) # At this point expected cppyy.LowLevelView but I got str
casted_uint16t_ptr = cppyy.ll.cast["uint16_t*"](uint16t_ptr)
print()
print(type(casted_char_ptr))
print(type(casted_uint16t_ptr))
print()
try:
cppyy.gbl.print_address(casted_char_ptr)
except TypeError as err:
print(err)
cppyy.gbl.print_address(casted_uint16t_ptr)
结果是:
address is: 0x7fff58b64847
address is: 0x7fff58b64846
<class 'str'>
<class 'cppyy.LowLevelView'>
void ::print_address(void* p) =>
TypeError: could not convert argument 1
address is: 0x7fff58b64846
Let's assume we have a char* named chr_ptr from some external library.
I tried to cast this pointer to char* by using cppyy.ll.cast["char*"](chr_ptr)
Expected: cppyy.LowLevelView
Actual: str
Other datatypes works well, this problem only occurs char(a.k.a. int8_t). Casting the pointer (let's say) int16_t is OK.
import cppyy
import cppyy.ll
if not hasattr(cppyy.gbl, "get_char_pointer"):
cppyy.cppdef("""
void* get_char_pointer()
{
char a = 1;
return &a;
}
""")
if not hasattr(cppyy.gbl, "get_uint16_t_pointer"):
cppyy.cppdef("""
void* get_uint16_t_pointer()
{
uint16_t a = 1;
return &a;
}
""")
if not hasattr(cppyy.gbl, "print_address"):
cppyy.cppdef("""
void print_address(void* p)
{
std::cout << "address is: " << p << std::endl;
}
""")
char_ptr = cppyy.gbl.get_char_pointer()
uint16t_ptr = cppyy.gbl.get_uint16_t_pointer()
cppyy.gbl.print_address(char_ptr)
cppyy.gbl.print_address(uint16t_ptr)
casted_char_ptr = cppyy.ll.cast["char*"](char_ptr) # At this point expected cppyy.LowLevelView but I got str
casted_uint16t_ptr = cppyy.ll.cast["uint16_t*"](uint16t_ptr)
print()
print(type(casted_char_ptr))
print(type(casted_uint16t_ptr))
print()
try:
cppyy.gbl.print_address(casted_char_ptr)
except TypeError as err:
print(err)
cppyy.gbl.print_address(casted_uint16t_ptr)
The result is:
address is: 0x7fff58b64847
address is: 0x7fff58b64846
<class 'str'>
<class 'cppyy.LowLevelView'>
void ::print_address(void* p) =>
TypeError: could not convert argument 1
address is: 0x7fff58b64846
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(1)
是的,
char*
是仅基于反射信息的类型之一,其预期用途并不明确。有一个半完成的补丁,允许修复函数/数据成员的char*
的独特含义,所以即将到来,是的,cast()
很明显,char*
更可能表示byte*
而不是 C 字符串,因此应该将其作为默认值。也就是说,在这种情况下,实际使用
std::byte*
(如果您不使用 C++17,则使用unsigned char*
)应该没问题指示结果应该是什么:根据需要生成
LowLevelView
。编辑:
签名字节
的解决方法:Yes,
char*
is one of those types that solely based on reflection information isn't clear in its intended use. There's a half-finished patch to allow fixing up functions/data members with what their unique meaning ofchar*
happens to be, so that's coming, and yes,cast()
is a clear case wherechar*
more likely meansbyte*
than C-string, so should have that as default.That said, in this case, it should be fine to actually use
std::byte*
(orunsigned char*
if you're not using C++17) to indicate what the result should be:which produces the
LowLevelView
as desired.Edit: workaround for
signed byte
: