Circular Import bei Ctypes
Verfasst: Mittwoch 15. Juli 2020, 20:44
Moin Community,
ich arbeite momentan das erste Mal mit ctypes und versuche, eine (relativ große) C-Bibliothek in Python zu wrappen mit ctypes. Nun besteht die Bibliothek aus recht vielen Structs, welche ich dann mit Python-Klassen wrappe. Nun habe ich ein Problem mit meinem Datenmodell.
Vereinfacht mal folgende Situation: In C existiert eine struct vector und die Methoden new_vector(), del_vector() und norm2_vector(). In Python habe ich nun eine Klasse Vector(ctypes.Structure) mit entsprechenden Methoden __init__(), __del__() und norm2().
Problem ist nun Folgendes:
Man kann sich vielleicht vorstellen, dass einige der C-Methoden mehr als nur einmal genutzt werden in Python. Daher wollte ich eine weitere Datei nutzen, lib_interface.py, die einfach alle Methoden der Bibliothek bereitstellt, welche ich dann überall importiere, wo sie gebraucht wird. Um allerdings die Methoden zu definieren, brauche ich die Wrapper-Klassen der structs, damit die Argumentstypen gesetzt werden können. Dabei entsteht ein Kreisimport.
Nun weiß ich leider nicht, wie ich dieses Problem umgehen kann, und hoffe hier auf Hilfe. Mir ist natürlich klar, dass ich die Methode immer da definieren kann, wo ich sie brauche, aber dann ist die Information, welche Methode welche Argumente hat, mehrfach vorhanden und damit redundant. Hiermal mein Beispiel in Codeform, um das Ganze etwas zu verdeutlichen:
Ich bin über Hilfe dankbar,
Gruß Plexian
ich arbeite momentan das erste Mal mit ctypes und versuche, eine (relativ große) C-Bibliothek in Python zu wrappen mit ctypes. Nun besteht die Bibliothek aus recht vielen Structs, welche ich dann mit Python-Klassen wrappe. Nun habe ich ein Problem mit meinem Datenmodell.
Vereinfacht mal folgende Situation: In C existiert eine struct vector und die Methoden new_vector(), del_vector() und norm2_vector(). In Python habe ich nun eine Klasse Vector(ctypes.Structure) mit entsprechenden Methoden __init__(), __del__() und norm2().
Problem ist nun Folgendes:
Man kann sich vielleicht vorstellen, dass einige der C-Methoden mehr als nur einmal genutzt werden in Python. Daher wollte ich eine weitere Datei nutzen, lib_interface.py, die einfach alle Methoden der Bibliothek bereitstellt, welche ich dann überall importiere, wo sie gebraucht wird. Um allerdings die Methoden zu definieren, brauche ich die Wrapper-Klassen der structs, damit die Argumentstypen gesetzt werden können. Dabei entsteht ein Kreisimport.
Nun weiß ich leider nicht, wie ich dieses Problem umgehen kann, und hoffe hier auf Hilfe. Mir ist natürlich klar, dass ich die Methode immer da definieren kann, wo ich sie brauche, aber dann ist die Information, welche Methode welche Argumente hat, mehrfach vorhanden und damit redundant. Hiermal mein Beispiel in Codeform, um das Ganze etwas zu verdeutlichen:
Code: Alles auswählen
# vector.py
from ctypes import Structure
import lib_interface as lib
class Vector(Structure):
_fields_ = [ ... ]
def __init__(self, dim):
self.obj = lib.new_vector(dim)
def __del__(self):
lib.del_vector(self.obj)
def norm(self):
return lib.norm2_vector(self.obj)
Code: Alles auswählen
# lib_interface.py
from ctypes import c_uint, c_double, POINTER as PTR
from vector import Vector
lib = ctypes.CDLL('lib/xyz.so')
def func(name, returntype, argtypes):
func = lib.__getattr__(name)
func.restype = returntype
func.argtypes = argtypes
return func
new_vector = func('new_vector', PTR(Vector), [c_uint])
del_vector = func('del_vector', None, [PTR(Vector)])
norm2_vector = func('norm2_vector', c_double, [PTR(Vector)]
Gruß Plexian