简体   繁体   English

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

[英]ctypes structure with char array empty in shared library

I have a shared C library with a struct I would like to use in my python code 我有一个共享的C库,其中包含我想在我的python代码中使用的结构

struct my_struct {
  char name[64];
};

so in python I recreate it with 所以在python中我重新创建它

class MyStruct(ctypes.Structure):
  _fields_ = [
    ("name", ctypes.c_char*64)
  ]

when I check the type of MyStruct.name i get 'str', whereas I expected 'c_char_Array_64'. 当我检查MyStruct.name的类型时,我得到'str',而我期望'c_char_Array_64'。

s=MyStruct()
print type(s.name) # <type 'str'>

So when I set the 'name' and try to use it, C sees it as blank. 因此,当我设置'name'并尝试使用它时,C将其视为空白。

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

where lib is the shared C library loaded with ctypes and my_func simply prints struct->name 其中lib是加载了ctypes的共享C库,my_func只是打印struct-> name

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

I would like to know why ctypes.Structure converts the char-array to a string and how to use it in the case specified above. 我想知道为什么ctypes.Structure将char数组转换为字符串以及如何在上面指定的情况下使用它。

Thank you 谢谢

Update & Solution 更新和解决方案

Tnanks to @CristiFati for the help on debugging this problem. 请到@CristiFati获取有关调试此问题的帮助。 I have marked his answer as correct as it is in fact the answer to the question posted. 我已将他的答案标记为正确,因为实际上是对所发布问题的答案。 In my case the problem was that the Structs were NOT of equal lengths in the Python and C program. 在我的例子中,问题是在Python和C程序中Structs的长度并不相同 So to whoever stumbles upon this question in the future, be very meticulous in checking that your Structs are in fact defined equally. 因此,对于将来偶然发现这个问题的人来说,要非常细致地检查你的结构是否实际上是平等的。

You're doing something wrong, but without looking at the full code I can't say what. 你做错了什么,但没有看完整的代码,我不能说什么。 So I prepared a small example that works. 所以我准备了一个有效的小例子。
I'm also posting [Python 3]: ctypes - A foreign function library for Python as a reference. 我也发布了[Python 3]:ctypes - 一个Python的外部函数库作为参考。

dll.c : dll.c

#include <stdio.h>
#include <stdlib.h> 

#if defined(_WIN32)
#  define DLL_EXPORT __declspec(dllexport)
#else
#  define DLL_EXPORT
#endif


typedef struct Struct0_ {
    char name[64];
} Struct0;


DLL_EXPORT void test(Struct0 *ps0){
    printf("Hello %s\n", ps0->name);
}

code.py : code.py

#!/usr/bin/env python3

import sys
import ctypes


DLL = "./dll.dll"

CharArr64 = ctypes.c_char * 64

class Struct0(ctypes.Structure):
    _fields_ = [
        ("name", CharArr64),
    ]


def main():
    dll_dll = ctypes.CDLL(DLL)
    test_func = dll_dll.test
    test_func.argtypes = [ctypes.POINTER(Struct0)]

    s0 = Struct0()
    s0.name = b"Martin"
    res = test_func(ctypes.pointer(s0))


if __name__ == "__main__":
    print("Python {:s} on {:s}\n".format(sys.version, sys.platform))
    main()

Output : 输出

 (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 

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM