структура ctypes с пустым массивом char в разделяемой библиотеке - PullRequest
0 голосов
/ 08 января 2019

У меня есть общая библиотека 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'>

Поэтому, когда я устанавливаю «имя» и пытаюсь использовать его, С видит его пустым.

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

где lib - это общая библиотека C, загруженная ctypes, а my_func просто печатает struct-> name

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

Я хотел бы знать, почему ctypes.Structure преобразует массив символов в строку и как использовать его в указанном выше случае.

Спасибо

Обновление и решение

Благодарим @CristiFati за помощь в устранении этой проблемы. Я отметил его ответ как правильный, поскольку на самом деле он является ответом на опубликованный вопрос. В моем случае проблема заключалась в том, что Structs НЕ были равной длины в программах Python и C. Поэтому, чтобы тот, кто столкнется с этим вопросом в будущем, очень тщательно проверил, что ваши Структуры на самом деле определены одинаково.

1 Ответ

0 голосов
/ 08 января 2019

Вы делаете что-то не так, но, не глядя на полный код, я не могу сказать, что. Поэтому я подготовил небольшой пример, который работает.
Я также публикую [Python 3]: ctypes - библиотека сторонних функций для Python в качестве ссылки.

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

#!/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()

выход

(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
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...