pythoncom & _midlSAFEARRAY

Python in C/C++ embedden, C-Module, ctypes, Cython, SWIG, SIP etc sind hier richtig.
zarathustra
User
Beiträge: 59
Registriert: Samstag 17. April 2010, 23:02

Hallo __deets__,

ich habe schlicht vom DLL-Monitor keine Ahnung. Ich wollte es ja ursprünglich nicht mit einer Lazarus-DLL machen. Ich dachte daran es rein mit Python zu tun. GUI mit wxWidgets und dann eben mit COM zu DesignCAD und ggf. aus Exceltabellen mit xlwings einige Werte holen (wenn's zu umfangreich wird ein GUI mit vielen Textboxen zu basteln). Ich habe den Monitor installiert, aber noch nicht wirklich verstanden wie der funktionert und was vor allem bei rauskommt, bzw. wo ich überhaupt nachsehen muß. So tief wollte ich da gar nicht rein.
Ich wollte einfach nur analog den Beispielen die ich Netz fand DesignCAD via COM ansprechen. Das verrückte ist, dass ja z.B der SetCommandPoint-Befehl für einen einzelnen Punkt ausgefürt wird, der Befehl SetCommandPoints -für mehrere Punkte auf einmal eben nicht.

Ich hatte über COM das Netz durchstöbert und man findet immer wieder nur die Standartbeispiele mit "Excel-Application" etc. Es kommt noch wie man mit makepy (win32com.client) oder GetModule (comtypes) eine Typbibliothek lädt. Aber wie man anschließend mit dem erzeugten Wrapper-Modul weiter verfährt, da wird's schon enger.

Ich dachte ja an LibreCAD. Aktuell keine Makrosprache. Ab Version 3 (sodenn sie iergendwann mal kommt) Lua als Makrosprache. Zum Mäusemelken. Warum können die nicht einfach Python nehmen??????? Es gibt eine Lua-Python-Bridge, aber das ist auch wieder gefummel denke ich.

Jetzt ist erstmal Wochenende. Ich wünsche Dir und allen im Forum ein schönes.

Viele Grüße

Zarathustra
__deets__
User
Beiträge: 14493
Registriert: Mittwoch 14. Oktober 2015, 14:29

Naja, gerade das der andere Teil geht zeigt ja, das der ursprüngliche Ansatz ok war. Nur eben das safearray macht Ärger. Wenn du da nicht tiefer einsteigen willst - ich kann’s nicht. Habe die Software nicht. Die Autoren von comtypes habrn da ggf mehr Ideen. Wobei ich mir auch gut vorstellen kann, das einfach irgendein anderer call drumrum fehlt.

Wofür brauchst du das cad überhaupt? Ggf kann das ja ersetzt werden. Zb mit FreeCad, das schon in Python Skriptbar ist.
zarathustra
User
Beiträge: 59
Registriert: Samstag 17. April 2010, 23:02

Es sollten Makros für das CAD werden. FreeCAD ist mehr auf 3D ausgelegt. Evtl. ist nur ein Workearound notwendig.

Gruß

Zarathustra
__deets__
User
Beiträge: 14493
Registriert: Mittwoch 14. Oktober 2015, 14:29

Das stimmt nicht -FreeCad ist basierend auf Open cascade & erlaubt CSG Modellierung von 3D Körpern.

Wie dem auch sei - in dein Problem muss man sich mehr reinknien. Ohne die Software zu haben kann ich das leider nicht.
zarathustra
User
Beiträge: 59
Registriert: Samstag 17. April 2010, 23:02

Leider finde ich den Downloadlink nicht mehr über den ich mir die Testversion 23 gezogen hatte. Ich hatte schon mal eine Version 17 bei Pearl für schmales Geld gekauft, die hat das gleiche Problem.

in comtypes.automation findet man ab Zeile 845 einen Kommentar zu Safearray. Leider kann ich damit nicht so all zuviel anfangen.

Ich hatte mal in Freecad reingesehen und ein Tutorial ausprobiert. Ich hatte den Eindruck, dass die Sketch-Funktion nur ein Hilfsmittel zur 3D Modellierung ist. Wenn ich nach CSG und OpenCascade schaue, dann ist das überwiegend 3D.

Momentan versuche ich gerade den Weg: Excel-xlwings-VBA-Desingcad. Mal sehen wie "gut" das geht...

Viele Grüße

Zarathustra
__deets__
User
Beiträge: 14493
Registriert: Mittwoch 14. Oktober 2015, 14:29

Verzeih. Ich hab mich irgendwie verlesen & 2D statt 3D in deinen Antworten angenommen. Insofern: ja, das ist für 3D & eher nicht für technische Zeichnungen. GLAUBE ich, probiert hab ich es nicht.

Was mich zur Frage bring: was willst du eigentlich erreichen? Es klingt ein bisschen nach einem XY-Problem. Wenn es zB nur um die Anlage technischer 2D Skizzen geht, dann ist es ggf viel besser direkt ein DXF zu erzeugen. Das kannst du dann importieren in DesignCAD, oder was auch immer mit machen.
zarathustra
User
Beiträge: 59
Registriert: Samstag 17. April 2010, 23:02

Hallo,

ich wollte u.a. Weg-Zeit-Diagramme in Straßenskizzen einbauen. Bzw. Zum Zeichnen von Kurven oder Einmündungen Makros verwenden.

Der Excel-Weg hat eine Besonderheit: Ich lasse via Python ein Numpy-Array mit 1000 Punkten errechnen, was die x-Werte eines Simus zwischen 0 und 2*pi darstellt. Aus den x und y Werten bastel ich dann das array für SetCommandPoints in VBA zusammen. Das funktioniert auch. Ich bekomme in DesigvCAD den Sinus gezeichnet. Erhöhe ich in "linspace" die ANzahl auf 10.000, dann wird nur noch die erste Halbwelle des Sinus dargestellt.

Gibt es dafür eine Erklärung?

Viele Grüße und schönes Wochenede

Zarathustra
__deets__
User
Beiträge: 14493
Registriert: Mittwoch 14. Oktober 2015, 14:29

Und welches Dateiformat liegt da dann vor? Oder brauchst du das CAD für Ankerpunkte?

Was dein Sinus-Problem angeht: kann ich nur raten. SetPoints mag ein internes limit haben, bzw. das CAD allgemein.
zarathustra
User
Beiträge: 59
Registriert: Samstag 17. April 2010, 23:02

Die Berechnungsergebnisse definieren einen Spline in der x-y-Ebene, dessen Startpunkt ich aber mit der Maus setzen möchte. Entlang des Splines wird dann die Aufsicht eines Modells entsprechend den Ergebnissen kopiert und ausgerichtet. Der Spline stellt die Fahrlinie eines Kfz dar. Das Modell ist die Aufsicht auf ein Kfz. Es könnte so ein Ausweichvorgang vor einem Hindernis dargestellt werden.

Dieses SetCommandPoints benötigt ein Array aus Punktetripeln (x1, y1, z1, x2, y2, z2, usw. mit z immer Null). Das gab damals bei Lazarus auch Probleme mit SafeArray, aber ich konnte es Typecasten. Das Typecasting funzt in Python scheinbar nicht.

Na ich hab's aufgegeben. Das Safearray ist vermutlich nicht das einzige Problem der Typebibliothek unter Python vernute ich.
zarathustra
User
Beiträge: 59
Registriert: Samstag 17. April 2010, 23:02

Hallo zusammen,

ich habe meine "Automatisierung" mal wieder aufgegriffen und bin tatsächlich dank __deets__ ein Stück weiter. Ich habe von "comtypes" wieder zurück auf "win32com" gewechselt und mit VARIANTS gearbeitet. Das hat dazu geführt, dass ich Numpy-Arrays an "SetCommandPoints()" übergeben kann und diese dann auch dargestellt werden.

Jetzt wollte ich einen Layer über sein "Item(Nummer)" anspreche. Wenn ich hier anstelle von Nummer eine Integer z.B. 4 eingebe, (DcLays.Item(4).Name = "Schraube") dann bekomme ich die Fehlermeldung:

'int' object has no attribute '_oleobj_'

Meine Frage: Wie "Typecaste" ich einen Integer in ein __oleobj__?

c_int(4) oder VARIANT wird auch nicht akzeptiert. Auch wenn ich z.B Lay = c_int(4) mit "byref(Lay)" an DcLay.Item(byref(Lay)).Name = "Schraube" übergebe gibt es die Meldung, dass das Übergebene kein __oleobj__ sei.

Die ganze Fehlermeldung:

File "C:\Python3.6.4-32\lib\site-packages\win32com\gen_py\DD0F69E1-1E0D-4064-94FA-2ED7ADC72C5Dx0x24x0.py", line 5754, in Item
ret = self._oleobj_.InvokeTypes(0, LCID, 1, (9, 0), ((16396, 1),),vNameOrIndex
AttributeError: 'int' object has no attribute '_oleobj_'


Hier die Funktion ab Zeile 5753:

def Item(self, vNameOrIndex=defaultNamedNotOptArg):
ret = self._oleobj_.InvokeTypes(0, LCID, 1, (9, 0), ((16396, 1),),vNameOrIndex
)
if ret is not None:
ret = Dispatch(ret, 'Item', '{CA4A3EE7-6459-4B89-9304-BCD960BD96A5}')
return ret



Vielen Dank für Tipps

Zarathustra
__deets__
User
Beiträge: 14493
Registriert: Mittwoch 14. Oktober 2015, 14:29

Ein Variant vom Typ Integer mit Wert 4 erstellen?
zarathustra
User
Beiträge: 59
Registriert: Samstag 17. April 2010, 23:02

Code: Alles auswählen

import win32com.client as win32
from ctypes import c_int, byref
from win32com.client import VARIANT
import pythoncom
Ich habe verschiedene VARIANT-Arten probiert:

Code: Alles auswählen

vLay = win32.VARIANT(pythoncom.VT_I4, 4)
vLay1 = win32.VARIANT(pythoncom.VT_BYREF | pythoncom.VT_I4, 4)
vLay2 = VARIANT(pythoncom.VT_BYREF | pythoncom.VT_ARRAY | pythoncom.VT_I4, 4)
dann kommt immer: AttributeError: 'VARIANT' object has no attribute '_oleobj_'

Nehme ich ein

Code: Alles auswählen

Lay = c_int(4)
und füge es ein:

Code: Alles auswählen

DcLays.Item(Lay).Name = "Schraube"
dann kommt:
AttributeError: 'c_long' object has no attribute '_oleobj_'

füge ich es mit "byref" ein:

Code: Alles auswählen

DcLays.Item(byref(Lay)).Name = "Schraube"
kommt:
AttributeError: 'CArgObject' object has no attribute '_oleobj_'

Das macht mich ratlos.

Zarathustra
zarathustra
User
Beiträge: 59
Registriert: Samstag 17. April 2010, 23:02

Muss man zusätzlich eine "stdole.tlb" wrappen und sich das was rausholen?

Zarathustra
Antworten