@LilaznEnzo

Как правильно вывести структуру из dll на c++ в Python?

Я не программист, учусь на том, что найду в инете. Есть потребность в выводе из dll не одного значения, а множества значений. Столкнулся с проблемой, которую описал чуть ниже. Подскажите как правильно решить поставленную задачу: связать питон и с++ dll; вывести структуру или просто множество значений, тут не суть важно что именно, главное, что значений много надо вывести; решить проблему с некорректной передачей вводных данных в dll.
Если выводить не структуру, а int, то программа работает полностью верно. Проблема с вводом появляется только если пытаюсь вывести структуру.

main файл на Python
import ctypes


SCoord = ctypes.CDLL(r'./Coord.dll')

x1 = ctypes.c_float(float(1))
x2 = ctypes.c_float(float(2))
x3 = ctypes.c_float(float(3))
x4 = ctypes.c_float(float(4))
x5 = ctypes.c_float(float(5))
x6 = ctypes.c_int(int(6))

rez1 = (SCoord.Coord(x1, x2, x3, x4, x5, x6))

print (rez1)


Если вывести из dll вводные данные, то они покажут значения: 2, 3, 4, 5, 8e-44, 1040117888.
Значения 1 и 6 потерялись, вместо них то, что не вводил. А сами вводные сместились. Не могу понять почему.

dll файл
#pragma once
typedef struct outdata 
{
	float out_xy1,
		out_xy2,
		out_xy3;
} ;
extern "C" __declspec(dllexport) outdata Coord(float, float, float, float, float, int);


C++ файл
#include <iostream>
#include <math.h>
#include <fstream>
#include <vector>
#include "..\Coord\Header.h"

using namespace std;

__declspec(dllexport) outdata Coord(float x1, float x2, float x3, float x4, float 5x, int x6)
{
cout << "x1 = " << x1 << endl;	//x1 ввод (1), но тут пишет иное число (2)
cout << "x2 = " << x2 << endl;	//x2 ввод (2), но тут пишет иное число (3)
cout << "x3 = " << x3 << endl; //x3 ввод (3), но тут пишет иное число (4)
cout << "x4 = " << x4 << endl; //x4 ввод (4), но тут пишет иное число (5)
cout << "x5 = " << x5 << endl; //x5 ввод (5), но тут пишет иное число (8e-44)
cout << "x6 = " << x6 << endl; //x6 ввод (6), но тут пишет иное число (1040117888)
//код

float xy1 = 1,
xy2 = 2,
xy3 = 3;

outdata data;
data.out_y1 = xy1; 
data.out_y2 = xy2;
data.out_y3 = xy3;
return data;
}
  • Вопрос задан
  • 268 просмотров
Решения вопроса 1
Vindicar
@Vindicar
RTFM!
Разумеется, тебе и реализацию функции надо будет поправить, её заголовок должен совпадать с тем, который ты описал в заголовочном файле. Это же азы!
Более того, у тебя и тело функции изменится. Теперь вместо
__declspec(dllexport) outdata SpiralsCoord(float x1, float x2, float x3, float x4, float x5, int x6) {
outdata data;
data.out_x1 = xy1;
data.out_x2 = xy2;
data.out_x3 = xy3;
return data;
}

будет код вроде
__declspec(dllexport) void SpiralsCoord(float x1, float x2, float x3, float x4, float x5, int x6, outdata* data) {
//используем оператор ->, так как data теперь указатель на структуру, а не сама структура
data->out_x1 = xy1; 
data->out_x2 = xy2;
data->out_x3 = xy3;
}

Ну а в Питоне тогда для передачи последнего параметера нужно будет сделать кое-что.
1. Описать структуру outdata как класс-потомок ctypes.Structure.
2. Создать экземпляр этой структуры.
3. Описать прототип функции SpiralsCoord (или под каким именем она экспортируется?), указав типы параметров и возвращаемого значения.
4. Использовать ctypes.byref() при передаче экземпляра структуры последним параметром.
Ответ написан
Комментировать
Пригласить эксперта
Ответы на вопрос 1
jcmvbkbc
@jcmvbkbc
"I'm here to consult you" © Dogbert
Возврат структуры по значению при определённых условиях (связанных с размером и типами данных полей структуры) добавляет скрытый параметр (указатель на область памяти куда нужно вернуть результат), который функция будет ожидать. Это твой случай, и поэтому все остальные параметры съехали на один. Решение -- либо научить ctypes тому, что возвращается сложный тип и у функции может быть скрытый параметр (полагаю, что так: ctypes.restype(outdata), где outdata -- тип rez1, см), либо переделать функцию так, чтобы она не требовала скрытого параметра (например, добавив явный указатель на результат в список параметров, см).
Ответ написан
Ваш ответ на вопрос

Войдите, чтобы написать ответ

Похожие вопросы