Hallo,
Ich möchte eine Funktion einer Hardware API, welche in C geschrieben ist aufrufen. Die ansteuerungssoftware für die Hardware ist in Python. Dir Funktion der API benötigt als Parameter ein Struct als Pointer. Dabei beinhaltet das Struct einen Parameter der ein weiteres struct benötigt.
Wie kann ich diese Funktion mit Python aufrufen und die jeweiligen Parameter mitgeben? Wie kann ich ein struct Aus c inmpython schreiben? Geht das auch ohne ctypes?
C Funktion in Python aufrufen (Parameter ist ein struct)
-
- User
- Beiträge: 29
- Registriert: Samstag 18. Juli 2009, 19:54
Nein, wie ich das oben genannte Problem lösen kann. Sprich ein Pointer auf ein struct a un d ein weiters struct b in dem struct a. Wie kann ich das programmieren?
-
- User
- Beiträge: 29
- Registriert: Samstag 18. Juli 2009, 19:54
Das hab ich mir gedacht aber wie kann ich das umsetzen? Kann mir mal jemand bitte Ei Beispiel zum o.g. Problem geben?
Hallo.
Das hat die Dokumentation zum Modul schon für uns erledigtzander180_0 hat geschrieben:Das hab ich mir gedacht aber wie kann ich das umsetzen? Kann mir mal jemand bitte Ei Beispiel zum o.g. Problem geben?
Das Leben ist wie ein Tennisball.
-
- User
- Beiträge: 29
- Registriert: Samstag 18. Juli 2009, 19:54
Ich hab bereits folgendes probiert aber weiss nicht ob es richtig ist. Die C-Funktion: test(porthandle handle, struct*param);
Das handle habe ich und bin mir auch sicher das das richtig ist. Python:
Class Signal(Structure):
[("a",c_int),("b",c_int)]
Class param(Structure):
[("Signal",Signal)
("test",c_int)]
Point = Signal(1,2)
Parameter=param(Point,5)
Ptr_Parameter = pointer(Parameter)
test(handle,Ptr_Parameter)
Ist das so richtig oder hab ich was falsch gemacht?
Natürlich hab ich ctypes eingebunden und die entsprechende dll für die C-Funktion
Das handle habe ich und bin mir auch sicher das das richtig ist. Python:
Class Signal(Structure):
[("a",c_int),("b",c_int)]
Class param(Structure):
[("Signal",Signal)
("test",c_int)]
Point = Signal(1,2)
Parameter=param(Point,5)
Ptr_Parameter = pointer(Parameter)
test(handle,Ptr_Parameter)
Ist das so richtig oder hab ich was falsch gemacht?
Natürlich hab ich ctypes eingebunden und die entsprechende dll für die C-Funktion
So sollte das in etwa gehen:
Wirst du vermutlich noch etwas anpassen müssen. `byref()` kann immer dann eingesetzt werden, wenn eine Funktion einen Zeiger erwartet, du ihn aber innerhalb von Python nicht benötigst. Das ist performanter, weil nur eine Art Fake konstruiert wird und sollte daher bevorzugt werden. Es kann übrigens nicht schaden, wenn du uns mal die C-Bibliothek nennst, da man dir dann wahrscheinlich besser helfen kann.
Und bitte antworte nachher nicht mit einem "geht aber nicht", sondern zeige den Codestand und die ggf geworfene Exception. Und wende den Knopf "python" (unterhalb der anderen Formatierungsbuttons) auf den Code an, damit er besser lesbar ist. Dann würdest du auch merken, dass er in seiner jetzigen Form nicht mal durch den Parser geht, was übrigens auch funktioniert, wenn man vor dem Fragen erstmal ausprobiert.
Code: Alles auswählen
class Signal(Structure):
_fields_ = [
('a', c_short),
('b', c_short)]
class Param(Structure):
_fields_ = [
('signal', Signal),
('test', c_int)]
param = Param()
test(handle, byref(param))
Und bitte antworte nachher nicht mit einem "geht aber nicht", sondern zeige den Codestand und die ggf geworfene Exception. Und wende den Knopf "python" (unterhalb der anderen Formatierungsbuttons) auf den Code an, damit er besser lesbar ist. Dann würdest du auch merken, dass er in seiner jetzigen Form nicht mal durch den Parser geht, was übrigens auch funktioniert, wenn man vor dem Fragen erstmal ausprobiert.
-
- User
- Beiträge: 29
- Registriert: Samstag 18. Juli 2009, 19:54
C-Code:
typedef u8_t G_Signal_ByteOrder_t;
typedef struct {
u8_t Size; // in bits
G_Signal_ByteOrder_t ByteOrder; //= little Endian
u16_t Offset; // in bits
} G_Signal;
typedef u8_t G_CyclicMsgs_Ramp_Direction_t;
#define G_CYCLIC_MSGS__RAMP__DIRECTION__UP \
((G_Can_CyclicMsgs_Ramp_Direction_t) 0x01)
typedef struct {
u32_t Id; //0x123
G_Signal_t Signal;
G_CyclicMsgs_Ramp_Mode_t Mode; //1
G_CyclicMsgs_Ramp_Direction_t Direction; //1
u16_t MinValue; //0
u16_t MaxValue; //15
u16_t UpdateRate; //1
float64_t Increment; //1
u32_t RampSum; //0
u16_t NumberOfFlanks; //0
u8_t reserved1; //0
u8_t reserved2; //0
} G_Can_CyclicMsgs_Ramp_Define_Parameters_t;
und nun meine Umsetzung in Python:
typedef u8_t G_Signal_ByteOrder_t;
typedef struct {
u8_t Size; // in bits
G_Signal_ByteOrder_t ByteOrder; //= little Endian
u16_t Offset; // in bits
} G_Signal;
typedef u8_t G_CyclicMsgs_Ramp_Direction_t;
#define G_CYCLIC_MSGS__RAMP__DIRECTION__UP \
((G_Can_CyclicMsgs_Ramp_Direction_t) 0x01)
typedef struct {
u32_t Id; //0x123
G_Signal_t Signal;
G_CyclicMsgs_Ramp_Mode_t Mode; //1
G_CyclicMsgs_Ramp_Direction_t Direction; //1
u16_t MinValue; //0
u16_t MaxValue; //15
u16_t UpdateRate; //1
float64_t Increment; //1
u32_t RampSum; //0
u16_t NumberOfFlanks; //0
u8_t reserved1; //0
u8_t reserved2; //0
} G_Can_CyclicMsgs_Ramp_Define_Parameters_t;
und nun meine Umsetzung in Python:
-
- User
- Beiträge: 29
- Registriert: Samstag 18. Juli 2009, 19:54
Sorry, hatte vergessen den python-code einzufügen. Hier nun alles noch mal komplett.
C-Code:
und nun meine Umsetzung in Python:
Ich habe es bis jetzt noch mit dem Pointer umgesetzt.
Was habe ich falsch gemacht
C-Code:
Code: Alles auswählen
typedef u8_t G_Signal_ByteOrder_t;
typedef struct {
u8_t Size; // in bits
G_Signal_ByteOrder_t ByteOrder; //= little Endian
u16_t Offset; // in bits
} G_Signal;
typedef u8_t G_CyclicMsgs_Ramp_Direction_t;
#define G_CYCLIC_MSGS__RAMP__DIRECTION__UP \
((G_Can_CyclicMsgs_Ramp_Direction_t) 0x01)
typedef struct {
u32_t Id; //0x123
G_Signal_t Signal;
G_CyclicMsgs_Ramp_Mode_t Mode; //1
G_CyclicMsgs_Ramp_Direction_t Direction; //1
u16_t MinValue; //0
u16_t MaxValue; //15
u16_t UpdateRate; //1
float64_t Increment; //1
u32_t RampSum; //0
u16_t NumberOfFlanks; //0
u8_t reserved1; //0
u8_t reserved2; //0
} G_Can_CyclicMsgs_Ramp_Define_Parameters_t;
und nun meine Umsetzung in Python:
Code: Alles auswählen
from ctypes import *
porthandle = c_uint(0)
point_porthandle = pointer(porthandle)
idMode = c_ubyte(0)
Id = c_uint(0x123)
class signal(Structure):
_fields_=[("Size",c_ubyte), ("Byteorder",c_ubyte),("Offset",c_ushort)]
point = signal(4,0,8)
class parameters(Structure):
_fields_=[("Id",c_uint),
("Signal",signal),
("Mode",c_ubyte),
("Direction",c_ubyte),
("MinValue",c_ushort),
("MaxValue",c_ushort),
("UpdateRate",c_ushort),
("Increment",c_uint64),
("RampSum",c_uint),
("NumberOfFlanks",c_ushort),
("reserved1",c_ubyte),
("reserved2",c_ubyte)]
foo= parameters(Id,(4,0,8),1,1,0,15,1,1,0,0,0,0)
ptr = pointer(foo)
error = GAPI_can.G_CyclicMsgs_Ramp_Define(porthandle,ptr)
Ich habe es bis jetzt noch mit dem Pointer umgesetzt.
Was habe ich falsch gemacht
Zuletzt geändert von Anonymous am Donnerstag 19. August 2010, 20:05, insgesamt 1-mal geändert.
Grund: C-Quelltext in Code-Tags gesetzt.
Grund: C-Quelltext in Code-Tags gesetzt.
@zander180_0: Ich habe nur mal so kurz drübergeschaut und mir ist `Increment` aufgefallen. Willst Du da wirklich den Wert 4.9406564584124654e-324 für übergeben? Das wäre nämlich eine Ganzahl 1 als 64-Bit Fliesskommazahl interpretiert.
Statt `c_ushort` würde ich auch `c_uint16` verwenden. Das mag vielleicht das gleiche sein, muss es aber nicht.
Statt `c_ushort` würde ich auch `c_uint16` verwenden. Das mag vielleicht das gleiche sein, muss es aber nicht.
-
- User
- Beiträge: 29
- Registriert: Samstag 18. Juli 2009, 19:54
Ich hatte gedacht, dass ich die Datentypen, welche das struct auf der Seite von c exakt übernehmen muss. Deshalb hatte ich c_ushort usw. genommen. Der c-Code ist von einer API einer Hardware. Ich bin somit für die parametrierung nich verantwortlich. Mich interessiert ob ich das alles richtig umgesetzt habe vor allem mit dem struct im struct sowie die Zuweisung der Parameter und das Aufrufen der Funktion.
@zander180_0: Weil der C-Code `u16_t` verwendet nimmst Du `c_ushort` statt `c_uint16` und `c_uint64` statt `c_double`? Das muss ich jetzt nicht verstehen, oder!?
-
- User
- Beiträge: 29
- Registriert: Samstag 18. Juli 2009, 19:54
Ok, wenn die Sache so ist, dann lass ich mich gern belehren. Welche Parameter sollten wie geaendert werden?
Ich Wäre über jeden Rat dankbar.
Ich Wäre über jeden Rat dankbar.