Warning: file_get_contents(/data/phpspider/zhask/data//catemap/3/arrays/14.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Python 共享库中字符数组为空的ctypes结构_Python_Arrays_String_Ctypes - Fatal编程技术网

Python 共享库中字符数组为空的ctypes结构

Python 共享库中字符数组为空的ctypes结构,python,arrays,string,ctypes,Python,Arrays,String,Ctypes,我有一个共享的C库,其中包含一个我想在python代码中使用的结构 struct my_struct { char name[64]; }; 因此,在python中,我使用 class MyStruct(ctypes.Structure): _fields_ = [ ("name", ctypes.c_char*64) ] 当我检查MyStruct.name的类型时,我得到的是'str',而我期望的是'c_char_Array_64' s=MyStruct() print

我有一个共享的C库,其中包含一个我想在python代码中使用的结构

struct my_struct {
  char name[64];
};
因此,在python中,我使用

class MyStruct(ctypes.Structure):
  _fields_ = [
    ("name", ctypes.c_char*64)
  ]
当我检查MyStruct.name的类型时,我得到的是'str',而我期望的是'c_char_Array_64'

s=MyStruct()
print type(s.name) # <type 'str'>
其中lib是加载了ctypes的共享C库,my_func只打印struct->name

void my_func(struct my_struct *s){
  printf("Hello %s\n", s->name);
}
我想知道为什么ctypes.Structure会将字符数组转换为字符串,以及在上面指定的情况下如何使用它

多谢各位

更新和解决方案
t请联系@CristiFati以获取调试此问题的帮助。我认为他的回答是正确的,因为这实际上是对所贴问题的回答。在我的例子中,问题是Python和C程序中的结构不是长度相等的。因此,无论谁在将来偶然发现这个问题,都要非常仔细地检查您的结构实际上是平等定义的。

您做错了什么,但如果不看完整的代码,我就说不出是什么。所以我准备了一个小例子
我也在作为推荐人发帖

dll.c:

#包括
#包括
#如果已定义(_WIN32)
#定义DLL\u导出\u declspec(dllexport)
#否则
#定义DLL_导出
#恩迪夫
类型定义结构0_{
字符名[64];
}结构0;
DLL_导出无效测试(结构0*ps0){
printf(“你好%s\n”,ps0->name);
}
code.py:

#/usr/bin/env蟒蛇3
导入系统
导入ctypes
DLL=“./DLL.DLL”
CharArr64=ctypes.c_char*64
类结构0(ctypes.Structure):
_字段=[
(“姓名”,CharArr64),
]
def main():
dll\u dll=ctypes.CDLL(dll)
test\u func=dll\u dll.test
test_func.argtypes=[ctypes.POINTER(Struct0)]
s0=结构0()
s0.name=b“Martin”
res=测试函数(ctypes.pointer(s0))
如果名称=“\uuuuu main\uuuuuuuu”:
打印(“Python{:s}on{:s}\n.”格式(sys.version,sys.platform))
main()
输出


你做错了什么,但是如果不看完整的代码,我就说不出什么。所以我准备了一个小例子
我也在作为推荐人发帖

dll.c:

#包括
#包括
#如果已定义(_WIN32)
#定义DLL\u导出\u declspec(dllexport)
#否则
#定义DLL_导出
#恩迪夫
类型定义结构0_{
字符名[64];
}结构0;
DLL_导出无效测试(结构0*ps0){
printf(“你好%s\n”,ps0->name);
}
code.py:

#/usr/bin/env蟒蛇3
导入系统
导入ctypes
DLL=“./DLL.DLL”
CharArr64=ctypes.c_char*64
类结构0(ctypes.Structure):
_字段=[
(“姓名”,CharArr64),
]
def main():
dll\u dll=ctypes.CDLL(dll)
test\u func=dll\u dll.test
test_func.argtypes=[ctypes.POINTER(Struct0)]
s0=结构0()
s0.name=b“Martin”
res=测试函数(ctypes.pointer(s0))
如果名称=“\uuuuu main\uuuuuuuu”:
打印(“Python{:s}on{:s}\n.”格式(sys.version,sys.platform))
main()
输出


你能展示一下my_func是如何在C语言中定义并用ctypes/python包装的吗?上面已经展示过了,你需要用python为你的函数定义argtypes(和重新类型)(
lib.my_func.argtypes=[ctypes.POINTER(MyStruct)]
,并将其命名为:
lib.my_func(ctypes.POINTER))
)。大多数ctypes失败都是由于这个原因。查看(以及大量其他问题)以了解更多详细信息。谢谢@CristiFati,我将尝试此功能抱歉@CristiFati,s->name仍然为空。我还有其他方法可以尝试吗?你能展示一下my_func是如何在C中定义的,以及如何用ctypes/python包装的吗?上面已经展示过了,你需要用python为你的函数定义argtypes(和重新类型)(
lib.my_func.argtypes=[ctypes.POINTER(MyStruct)]
,并调用它:
lib.my_func(ctypes.POINTER(s))
)。大多数ctypes失败都是由于这个原因。查看(以及大量其他问题)以了解更多详细信息。谢谢@CristiFati,我将尝试此功能抱歉@CristiFati,s->name仍然为空。我可以尝试其他方法吗?我最好的猜测是OP没有为函数设置argtypes,因此结构是通过值而不是指针传递的。也就是说,函数将字符串
'Martin\0\0'
解释为指向
MyStruct
的指针。例如,比较
libc.printf(b'hello%sn',s)
libc.printf(b'hello%s\n',ctypes.byref(s))
。前者打印垃圾,而后者则将指向
s
的指针作为第二个参数传递(恰好与指向
s->name
的指针相同)。@Dunes:我在一条注释中指定了函数的调用方式,根据下一条注释,该操作已经完成。然后我真的很想看看我是否可以复制它,我发布了答案。@CristiFati我已经尝试了你的代码,它工作得非常完美。甚至尝试将它移植回我的代码看起来的样子,但它仍然有效。我还没有发布“全部代码”,因为这是一个我正在构建的大型项目,我认为我发布的内容足以发现问题。但事实并非如此。代码中一定有其他地方干扰了“通过引用传递”的工作方式。我感谢您的帮助。在这个场景中,它与如何从Python调用函数有关。代码中有两个位置:
ctypes.POINTER
ctypes.POINTER
,它们是关键,您可能错过了其中一个。或者可能是您做了更改(在C源代码中),但忘记了重建.SOLVED@克里斯蒂法蒂。我发现并发布了,正如你所说的“没有看到整个代码…”。事实证明,python和C中的结构长度不相等,这造成了数据实际所在位置的不匹配。我仍然会接受你的回答,因为这实际上是对所述问题的回答。谢谢你的帮助。我最好的猜测是OP没有为函数设置argtypes,因此结构是通过值而不是指针传递的。也就是说,函数将字符串
'Martin\0\0'
解释为poin
void my_func(struct my_struct *s){
  printf("Hello %s\n", s->name);
}
(py_064_03.06.08_test0) e:\Work\Dev\StackOverflow\q054089371>"c:\Install\x86\Microsoft\Visual Studio Community\2015\vc\vcvarsall.bat" x64

(py_064_03.06.08_test0) e:\Work\Dev\StackOverflow\q054089371>dir /b
code.py
dll.c

(py_064_03.06.08_test0) e:\Work\Dev\StackOverflow\q054089371>cl /nologo /DDLL /MD dll.c  /link /NOLOGO /DLL /OUT:dll.dll
dll.c
   Creating library dll.lib and object dll.exp

(py_064_03.06.08_test0) e:\Work\Dev\StackOverflow\q054089371>dir /b
code.py
dll.c
dll.dll
dll.exp
dll.lib
dll.obj

(py_064_03.06.08_test0) e:\Work\Dev\StackOverflow\q054089371>"e:\Work\Dev\VEnvs\py_064_03.06.08_test0\Scripts\python.exe" code.py
Python 3.6.8 (tags/v3.6.8:3c6b436a57, Dec 24 2018, 00:16:47) [MSC v.1916 64 bit (AMD64)] on win32

Hello Martin

(py_064_03.06.08_test0) e:\Work\Dev\StackOverflow\q054089371>rem Also run with Python 2.7 ... Not recommended.

(py_064_03.06.08_test0) e:\Work\Dev\StackOverflow\q054089371>"e:\Work\Dev\VEnvs\py_064_02.07.15_test0\Scripts\python.exe" code.py
Python 2.7.15 (v2.7.15:ca079a3ea3, Apr 30 2018, 16:30:26) [MSC v.1500 64 bit (AMD64)] on win32

Hello Martin