共享库中 char 数组为空的 ctypes 结构

问题描述 投票:0回答:1

我有一个共享 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'>

因此,当我设置“名称”并尝试使用它时,C 将其视为空白。

s.name="Martin"
lib=ctypes.cdll.LoadLibrary('./mylib.so')
lib.my_func(s) # prints ''

其中 lib 是加载了 ctypes 的共享 C 库,而 my_func 只是打印 struct->name

void my_func(struct my_struct *s){
  printf("Hello %s\n", s->name);
}

我想知道为什么 ctypes.Structure 将 char 数组转换为字符串以及如何在上面指定的情况下使用它。

谢谢你

更新及解决方案

Tnanks 向@CristiFati 寻求调试此问题的帮助。我已将他的答案标记为正确,因为它实际上是所发布问题的答案。就我而言,问题在于 Python 和 C 程序中的结构体不是“等长”的。因此,对于将来偶然发现这个问题的人,请非常仔细地检查您的结构是否实际上是平等定义的。

python arrays string ctypes
1个回答
5
投票
我还发布了

[Python.Docs]:ctypes - Python 的外部函数库
作为参考。

dll00.c

: #include <stdio.h> #include <stdlib.h> #if defined(_WIN32) # define DLL00_EXPORT __declspec(dllexport) #else # define DLL00_EXPORT #endif typedef struct Struct0_ { char name[64]; } Struct0; DLL00_EXPORT void test(Struct0 *ps0) { printf("Hello %s\n", ps0->name); }

code00.py

#!/usr/bin/env python import ctypes as cts import sys DLL_NAME = "./dll00.{:s}".format("dll" if sys.platform[:3].lower() == "win" else "so") CharArr64 = cts.c_char * 64 class Struct0(cts.Structure): _fields_ = ( ("name", CharArr64), ) def main(): dll = cts.CDLL(DLL_NAME) test = dll.test test.argtypes = (cts.POINTER(Struct0),) s0 = Struct0() s0.name = b"Martin" res = test(cts.pointer(s0)) if __name__ == "__main__": print( "Python {:s} {:03d}bit on {:s}\n".format( " ".join(elem.strip() for elem in sys.version.split("\n")), 64 if sys.maxsize > 0x100000000 else 32, sys.platform, ) ) rc = main(*sys.argv[1:]) print("\nDone.\n") sys.exit(rc)

输出

(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 code00.py dll00.c (py_064_03.06.08_test0) e:\Work\Dev\StackOverflow\q054089371> cl /nologo /DDLL /MD dll00.c /link /NOLOGO /DLL /OUT:dll00.dll dll00.c Creating library dll00.lib and object dll00.exp (py_064_03.06.08_test0) e:\Work\Dev\StackOverflow\q054089371> dir /b code00.py dll00.c dll00.dll dll00.exp dll00.lib dll00.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" ./code00.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 Done. (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" ./code00.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 Done.
可能还想检查
[SO]:通过ctypes从Python调用的C函数返回不正确的值(@CristiFati的答案)

© www.soinside.com 2019 - 2024. All rights reserved.