@funkheld:
Offensichtlich hast Du meinen letzten Post zu den Aufrufkonventionen ignoriert, ansonsten wäre Dir der Unterschied zwischen ProcedureDLL und -CDLL klar. Übertragen auf dein jetziges Problem heisst das, dass Freebasic unter Windows nur stdcall unterstützt. Damit werden auch die Symbole mit dem Funktionsname@Nummer in der DLL erklärbar.
PS: Ich kenne Freebasic nicht, allerdings scheint es auch cdecl zu verstehen. Siehe http://www.lowlevel.eu/wiki/FreeBASIC, zweites Beispiel.
Eine Nichtypische Windows-Dll-Funktion aufrufen mit Python?
@jerch: Die verschiedenen Aufrufkonventionen, die FreeBASIC unterstützt, werden in dessen Dokumentation (kann man als CHM-Datei von der Homepage herunterladen) ausführlich erklärt. Was sie technisch gesehen bedeuten und wo sie eingesetzt werden -- sowohl Sprachen als auch Betriebssysteme. Und ziemlich am Anfang von der `ctypes`-Dokumentation steht auch etwas dazu -- sogar mit den gleichen Begriffen für die beiden Konventionen, die beide Seiten beherrschen. (FreeBASIC kennt noch eine dritte Variante, ``pascal``, die neben dem Namensgeber auch vom Vorbild QBasic und von Windows 3.x verwendet wird.)
Hmmm...., ist schon ein graus.
Du hast recht, Freebasic macht anderen Mist.
Hab jetzt mal "XBLITE" , ist Freeware ausprobiert,... , macht eigentlich gute Sachen.
Davon laufen die DLL, bis auf die Floatrückgabe bzw Floatausgabe von Python.
Die Ausgabe von "d" ist "nan", also 3 Zeichen. Wie kommt die Floatausgabe hier?
XBLite:
Du hast recht, Freebasic macht anderen Mist.
Hab jetzt mal "XBLITE" , ist Freeware ausprobiert,... , macht eigentlich gute Sachen.
Davon laufen die DLL, bis auf die Floatrückgabe bzw Floatausgabe von Python.
Die Ausgabe von "d" ist "nan", also 3 Zeichen. Wie kommt die Floatausgabe hier?
Code: Alles auswählen
from sys import *
import ctypes
f = ctypes.windll.LoadLibrary("pydll.dll")
f.multf.restype = ctypes.c_float
c=10.788
d=f.multf(ctypes.c_float(c))
print d >>>>>>>>>>> ausgabe ist "nan" als Buchstaben ???
Code: Alles auswählen
PROGRAM "pydll"
EXPORT
DECLARE FUNCTION multf ( SINGLE varf)
END EXPORT
FUNCTION multf (SINGLE varf)
SINGLE wertf
wertf=11.5*varf
RETURN wertf
END FUNCTION
END PROGRAM
@funkheld: FreeBASIC mach keinen "anderen Mist", sondern lässt Dir die Wahl. Du musst sie nur treffen und auf beiden Seiten -- FreeBASIC und `cpython` -- das jeweils passende wählen.
"Not a number" ("nan") ist der Wert für Ergebnisse die keine Zahl sind. Du verwendest wahrscheinlich in BASIC den falschen Datentyp. ``SINGLE`` klingt nach 4-Byte Fliesskommazahlen, `float` ist in Python aber 8 Bytes gross.
Edit: Sehe gerade dass Du ja `c_float` verwendet hast, daran kann es dann also nicht liegen. Dann weiss ich's auch nicht.
"Not a number" ("nan") ist der Wert für Ergebnisse die keine Zahl sind. Du verwendest wahrscheinlich in BASIC den falschen Datentyp. ``SINGLE`` klingt nach 4-Byte Fliesskommazahlen, `float` ist in Python aber 8 Bytes gross.
Edit: Sehe gerade dass Du ja `c_float` verwendet hast, daran kann es dann also nicht liegen. Dann weiss ich's auch nicht.
Ja, sonst funktioniert es wunderbar in XBLite mit der DLL.
Ich brauch mich hier auch nicht mehr um ASM-Code zu kümmern.
Der XBLite schlägt alle Recorde.
Um einen bestimmten Bildpunkt auszuwerten aus einem 100kbBild, braucht er für das Arry, welches ich von Python übergebe 0.05 sec.
Eine Forschleife 10000000 mit 10000000x einen Wert an eine Variable zu übergeben braucht er 0.5 sec. So etwas brauche ich unter anderem bei dem Pythoninterpreter.
Der hat andere Stärken.
Gruss
Ich brauch mich hier auch nicht mehr um ASM-Code zu kümmern.
Der XBLite schlägt alle Recorde.
Um einen bestimmten Bildpunkt auszuwerten aus einem 100kbBild, braucht er für das Arry, welches ich von Python übergebe 0.05 sec.
Eine Forschleife 10000000 mit 10000000x einen Wert an eine Variable zu übergeben braucht er 0.5 sec. So etwas brauche ich unter anderem bei dem Pythoninterpreter.
Der hat andere Stärken.
Gruss
FYI: Es funktionieren beide Aufrufkonventionen mit FreeBASIC und Python ctypes, sowohl cdecl als auch stdcall.
cdecl:
stdcall:
cdecl:
Code: Alles auswählen
FUNCTION multf CDECL ALIAS "multf" (c AS SINGLE) AS SINGLE EXPORT
RETURN c*5
END FUNCTION
Code: Alles auswählen
>>> import ctypes
>>> p=ctypes.cdll.LoadLibrary('bla.dll')
>>> p.multf
<_FuncPtr object at 0x00A2EB70>
>>> multf=p.multf
>>> multf.restype=ctypes.c_float
>>> multf(ctypes.c_float(5.1))
25.5
Code: Alles auswählen
FUNCTION multf STDCALL ALIAS "multf" (c AS SINGLE) AS SINGLE EXPORT
RETURN c*5
END FUNCTION
Code: Alles auswählen
>>> import ctypes
>>> p=ctypes.windll.LoadLibrary('bla.dll')
>>> multf = getattr(p, 'multf@4')
>>> multf.restype = ctypes.c_float
>>> multf(ctypes.c_float(5.1))
25.5
Verstehe leider den zweiten Teil der Frage nicht. Die Zeiger-Übergabe machst Du in Python z.B. mit ctypes.byref(). Gönn' Dir doch mal die 10min zum Durchlesen der ctypes-Einführung, da steht das alles mit Bsp. erklärt.funkheld hat geschrieben:Wie funktionieren da die Zeigerübergabe an die DLL, wo dann evtl Daten übergeben werden in der DLL.
Auf welche Reihenfolge spielst Du an? Reihenfolge der Parameter auf dem Stack?funkheld hat geschrieben:Im Forum konnte bis jetzt noch keiner sagen wie die Reihenfolge ist beim Aufruf.