Вызов C ++ dll из python - PullRequest
       9

Вызов C ++ dll из python

2 голосов
/ 09 октября 2019

Я создал библиотеку dll на c ++ и экспортировал ее как c dll типа. Заголовок библиотеки такой: library.h

struct Surface
{
    char surfReq[10];
};

struct GeneralData
{
    Surface surface;
    char weight[10];
};

struct Output
{
    GeneralData generalData;
    char message[10];
};
extern "C" __declspec(dllexport) int __cdecl Calculation(Output &output);

library.cpp

int Calculation(Output &output)
{
  strcpy_s(output.message, 10, "message");
  strcpy_s(output.generalData.weight, 10, "weight");
  strcpy_s(output.generalData.surface.surfReq, 10, "surfReq");
  return 0;
}

Теперь у меня есть скрипт Python:

#! python3-32
from ctypes import *
import sys, os.path

class StructSurface(Structure):
    _fields_ = [("surfReq", c_char_p)]

class StructGeneralData(Structure):
    _fields_ = [("surface", StructSurface),
                ("weight", c_char_p)]

class OutData(Structure):
    _fields_ = [("generalData", StructGeneralData),
                ("message", c_char_p)]

my_path = os.path.abspath(os.path.dirname(__file__))
path = os.path.join(my_path, "../../../libs/Python.dll")

testDll = cdll.LoadLibrary(path)

surfReq = (b''*10)
structSurface = StructSurface(surfReq)

weight = (b''*10)
structGeneralData = StructGeneralData(structSurface, weight)

message = (b''*10)
outData = OutData(structGeneralData, message) 

testDll.restyp = c_int
testDll.argtypes = [byref(outData)]
testDll.Calculation(outData)
print(outData.message)
print(outData.generalData.weight)
print(outData.generalData.surface.surfReq)

Когда я печатаю поля из outData, я получаю одинаковые результаты во всех них:

b'surfReq '

b'surfReq'

b'surfReq '

Подскажите, пожалуйста, как указать массивы / поля символов, чтобы я получил правильный результат. Мне разрешено только изменять скрипт на python. Я вызвал эту библиотеку из C # без проблем.

1 Ответ

0 голосов
/ 10 октября 2019

Изменил типы python на c_char * 10:

class StructSurface(Structure):
    _fields_ = [("surfReq", c_char * 10)]

class StructGeneralData(Structure):
    _fields_ = [("surface", StructSurface),
                ("weight", c_char * 10)]

class OutData(Structure):
    _fields_ = [("generalData", StructGeneralData),
                ("message", c_char * 10)]

И изменил argtypes и фактический вызов на

testDll.argtypes = [POINTER(OutData)]
testDll.Calculation(byref(outData))
...