|
Das deutsche QBasic- und FreeBASIC-Forum Für euch erreichbar unter qb-forum.de, fb-forum.de und freebasic-forum.de!
|
Vorheriges Thema anzeigen :: Nächstes Thema anzeigen |
Autor |
Nachricht |
tom_dehn
Anmeldungsdatum: 05.10.2015 Beiträge: 30
|
Verfasst am: 05.10.2015, 23:15 Titel: Reproduzierbarer Bug bei Funktionen mit overload |
|
|
"Vorwort"
Es war eine ganze Menge Arbeit, dem nachfolgend beschriebenen Fehler
auf die Spur zu kommen. Und noch mehr, den Code so einzudampfen,
daß er nachvollziehbar und repoduzierbar ist.
Immerhin weiß ich jetzt, daß ich zumindest in diesem Fall gründlich
gearbeitet habe. Auch ein Trost...
Kurze Beschreibung: OVERLOAD funktioniert nicht (nähere Umstände im
Code) so wie es in der CHM-Datei / in der Referenz steht. Kein "echter"
Compilerfehler, vermutlich, sondern eher ein "falsches GOTO" oder so was
Achtung: So, wie der Code _jetzt_ aussieht, ist alles in Ordnung, aber
beim Versuch, das Ganze in eine DLL oder LIB auszulagern (=EXTERN),
schlägt die Übersetzung fehl.
Zur Fehlererzeugung also die Kommentarfüsschen rausnehmen, und
schon geht das Theater los
Code: |
'' overloadbug.bas: title "reproducable bug in overload handling"
'' tested fbc 1.01 & 1.04 /32
''
'' 2015-10-05 20.49.03
'' tom_dehn
/'
Löscht man die Kommentare für die EXTERN-Anweisungen, meckert der
Assembler (s. Ende des Listing). Erstaunlich - "Extern" geht doch
bestenfalls den Linker an, nicht aber die Code-Erzeugung und die
Labels und so weiter. Denk ich mal, so unbedarft.
Es gibt zwar work-arounds, aber unbefriedigend ist es allemal.
Seltsam auch, daß es ausser mir bisher offenbar keiner gemerkt zu
haben scheint. So zu sagen eine "Erstbesteigung" :-)
'/
/'
un-commenting the EXTERN declarations, ASM will complain (see end
of code)
Why ASM ? Why not the Linker ?
It might be a misplaced #ifdef or s.th. like that.
This is very annoying. I knew it _is_ a bug, but it took me quite
a while to isolate it - let alone the time I spent condensing the
code to a reasonable size.
BTW, there are some similar oddities in Object/UDT handling as
well, but I didn`t have the time to extract the problem and write
down some evaluable code to reproduce the errors.
'/
'' Extern "Windows" Lib "overloadbug"
Declare Function fn OverLoad (s1 As String, n1 As Single) As String
Declare Function fn OverLoad (s1 As String ) As String
Declare Function fn OverLoad (n1 As Single, s1 As String) As String
Declare Function fn OverLoad ( n1 As Single) As String
Declare Function fn OverLoad () As String
'' End Extern
Function fn OverLoad (s1 As String, n1 As Single) As String
print s1,n1
RETURN "s1,n1"
end function
Function fn OverLoad (s1 As String ) As String
print s1
RETURN "s1"
end function
Function fn OverLoad (n1 As single, s1 as string ) As String
print n1,s1
RETURN "n1,s1"
end function
Function fn OverLoad (n1 as single ) As String
print n1
RETURN "n1"
end function
Function fn OverLoad () As String
print "?"
RETURN "?"
end function
'' MAIN()
print fn ("str",3.14)
fn "str",3.14
fn
print fn()
sleep
/' hier die oder wenigstens einige der Fehlermeldungen beim
Kompilieren. OHNE die EXTERN-Anweisungen wird es an-
standslos übersetzt.
Es ist übrigens egal, ob die "declares" in einer .bi stehen oder
direkt im Code. Und die Test-Ausgaben nach ""MAIN() stören nicht mal
bei einer DLL (Erfahrungswerte, bisher hat so was immer geklappt)
c:\prg\fbc\\fbc -s console "overloadbug.bas"
overloadbug.asm: Assembler messages:
overloadbug.asm:71: Error: symbol `_fn@8' is already defined
overloadbug.asm:104: Error: symbol `_fn@4' is already defined
Make done
'/ |
|
|
Nach oben |
|
|
St_W
Anmeldungsdatum: 22.07.2007 Beiträge: 949 Wohnort: Austria
|
Verfasst am: 06.10.2015, 12:45 Titel: |
|
|
Funktionen, die exportiert werden müssen grundsätzlich immer einen eindeutigen Namen haben, der nicht mehrfach verwendet wird. Nun gibt es je nachdem mit welchem Compiler man zusammenarbeitet eine Vielzahl an Schnittstellenspezifikationen.
Unter Windows ist es üblich (C) Funktionen unter demselben Namen zu exportieren, den sie tragen; also eine Funktion "MyFn" wird auch als "MyFn" exportiert. Dies entspricht in FB dem Export-Typ "Windows-MS".
Oft wird auch die gesamte Byte-Länge der Parameter an den Funktionsnamen angehängt, um einige binäre Inkompatibilitäten auszuschließen; bei einer Funktion "MyFn ( a as long, b as long )" wäre das dann "MyFn@8". Dies entspricht in FB dem Export-Typ "Windows".
Wie du siehst unterscheiden sich bei beiden Funktions-Dekorationen die Namen nicht, wenn Funktionen überladen werden (und die Parametergröße gleich ist bei letzterem). Diese zwei Funktionsdeklaration sind deshalb nur für C Funktionen möglich (in C gibt es keine überladenen Funktionen).
Wie du vielleicht weißt gibt es in C++ überladene Funktionen. Damit diese exportiert werden können dekoriert der C++ Compiler den Funktionsnamen entsprechend um einen eindeutigen Namen zu erzielen. Es werden z.B. die Datentypen der Parameter in den Namen mit aufgenommen. Die Funktion "MyFn ( a as integer )" würde z.B. vom GNU compiler als "_Z4MyFni" exportiert. Bei anderen C++ Compilern würde das anders aussehen, denn wie die Typen kodiert werden ist nicht standardisiert. Mit dieser Dekorierung von (Funktions)Namen (Stichwort "name mangling") ist es also auch möglich überladene Methoden zu exportieren. In FB entspricht dies dem Extern-Typ "C++".
Was allerdings laut Doku mit Extern C++ einhergeht ist die Einstellung der Aufrufkonvention auf Cdecl. Das ist im Grunde kein Problem, du musst nur sicherstellen dass bei Deklaration und Implementierung dieselbe Aufrufkonvention verwendet wird.
Das von dir beobachtete Verhalten ist also nicht unbedingt ein Compiler Bug, sondern schlicht die konzeptuelle Unverträglichkeit von Überladenen Funktion mit der gewählten Namens-Dekorierung. Was jedoch der Compiler besser machen könnte wäre eine sprechendere Fehlermeldung auszugeben, insb. Personen, die mit den technischen Details nicht so vertraut sind, würde das helfen.
Insbesondere auf x86 ist die Vielzahl an verschiedenen Namens-Dekorierungen und Aufrufkonventionen leider etwas kompliziert, da alles historisch gewachsen ist.
tom_dehn hat Folgendes geschrieben: | Es war eine ganze Menge Arbeit, dem nachfolgend beschriebenen Fehler auf die Spur zu kommen. Und noch mehr, den Code so einzudampfen, daß er nachvollziehbar und repoduzierbar ist. Immerhin weiß ich jetzt, daß ich zumindest in diesem Fall gründlich gearbeitet habe. Auch ein Trost... | Im Forum sowie im IRC sind Fragen zu Problemen wie diesem übrigens immer willkommen. Das könnte möglicherweise helfen die Fehlersuche verkürzen. _________________ Aktuelle FreeBasic Builds, Projekte, Code-Snippets unter http://users.freebasic-portal.de/stw/
http://www.mv-lacken.at Musikverein Lacken (MV Lacken) |
|
Nach oben |
|
|
grindstone
Anmeldungsdatum: 03.10.2010 Beiträge: 1211 Wohnort: Ruhrpott
|
Verfasst am: 06.10.2015, 13:03 Titel: |
|
|
Hallo tom_dehn und willkommen im Forum
Warum willst du dir mit dem Extern "Windows" denn unnötig das Leben schwermachen? Die Sache kann (so) nicht funktionieren, weil du damit die interne Verwaltung von FB durcheinanderbringst.
Zur Fehlerursache: Normalerweise behandelt FB überladene Funktionen so, daß es intern an den Namen eine Nummer anhängt. Durch das Extern "Windows" gibst du dem Compiler aber (unter anderem) die Anweisung, an jeden Funktionsnamen ein "@N" anzuhängen, wobei N die Gesamtzahl der Bytes aller Parameter ist. Das sind bei (s1 As String, n1 As Single) und (n1 As Single, s1 As String) jeweils 8 Bytes und bei (s1 As String ) und ( n1 As Single) 4 Bytes. Daher kommen "_fn@8" und "_fn@4" jeweils zweimal vor, und das gibt eine Fehlermeldung. Du siehst also: "It's not a bug, it's a feature"
Wenn du weiterhin "Extern" benutzen möchtest, mußt du zusehen, daß jede Funktion eine unteschiedliche Anzahl von Bytes mitbekommt, z.B. indem du (s1 As String) durch (s1 As String, d1 As Integer = 0, d2 As Integer = 0) und (n1 As Single, s1 As String) durch (n1 As Single, s1 As String, d1 As Integer = 0, d2 As Integer = 0 ) ersetzt. Durch diese Dummy - Parameter bekommt jede Funktion intern einen einmaligen Namen und die Fehlermeldungen verschwinden.
Gruß
grindstone
EDIT: Upps, da war St_W schneller. _________________ For ein halbes Jahr wuste ich nich mahl wie man Proggramira schreibt. Jetzt bin ich einen! |
|
Nach oben |
|
|
tom_dehn
Anmeldungsdatum: 05.10.2015 Beiträge: 30
|
Verfasst am: 06.10.2015, 21:24 Titel: |
|
|
Hi, St_W und Grindstone,
vielen Dank für Eure Antworten. Und den Willkommensgruss
Vor allem, Dank für die Ausführlichkeit. Ohne Scherz oder Ironie. Gute Arbeit.
Jetzt weiss ich wenigstens, was da los ist.
Und falls der Ausdruck "Bug" zu hart klingt, können wir mein Gemeckere auch gern herunter-"diplomatisieren".
Beispielsweise als "Verhalten des Compilers, das einer gewissen Untermenge der Benutzer als unzulänglich dokumentiert erscheinen mag, sich jedoch dem multilingualen Code-Produzenten allein schon aus dessen mehrjähriger Erfahrung (St_W: seit 2007 dabei, grindstone: seit 2010) erschliessen wird."
Oder, wie es St_W so schön umschreibt, kein Bug, sondern " [das] beobachtete Verhalten ist also nicht unbedingt ein Compiler Bug, sondern schlicht die konzeptuelle Unverträglichkeit von Überladenen Funktion mit der gewählten Namens-Dekorierung."
Die Umdeklarierung dieses Verhaltens zu einem Feature lassen wir mal als Flapsigkeit durchgehen (diesmal: Scherz==TRUE)
Davon abgesehen: Wenn der Linker / Compiler für "C" eine etwas begrenzte Sicht der Dinge hat, oder aber der Compiler, Linker oder sonstwer irgendwelche Nummern anhängt oder so (jaaa, ich habe es begriffen, aber ich stell mich halt dumm), wieso kann er dann nicht von sich aus solche Konflikte vermeiden?
Im Ernst: Das Ganze sollte dann aber auch in der DOC zu FreeBASIC drinstehen, nicht nur in der von C / C# /C++ / Java oder sonstwo. Und zwar so deutlich, daß es auch deutlich wird.
Aber so lange sich keiner bereit erklärt, ernstlich dem, so klingt er zumindest, überlasteten Nemored bei der Referenz zu helfen, oder auch nur wohldokumentierten Quellcode hochzuladen...
OK. Ich werde mir diese Theorien und Fakten mal reinziehen, vielleicht kann ich ja auch ein bißchen was Praktisches draus basteln. Man liest sich.
Tom
|
|
Nach oben |
|
|
nemored
Anmeldungsdatum: 22.02.2007 Beiträge: 4597 Wohnort: ~/
|
Verfasst am: 06.10.2015, 22:10 Titel: |
|
|
Wenn ich das richtig verstehe, ist der Compiler durchaus in der Lage, eindeutige Namen zu wählen, aber die Windows-Deklaration ist es nicht, und wenn diese Art der Deklaration gewählt wird, kann der Compiler auch nicht mehr viel dagegen tun. Er wurde ja angewiesen, sich genau an diese Deklaration halten.
Ein grundsätzliches Problem ist, dass hier ein C-Compiler eingesetzt wird und es den Rahmen der FreeBASIC-Sprachreferenz sprengen würde, sämtliche Eigenheiten dieses Compilers und des Assemblers und des Linkers usw. detailiert aufzulisten (ich überspitze etwas, aber im Großen und Ganzen läuft es darauf hinaus). Selbstverständlich schadet es nicht, im Eintrag zu EXTERN auf das Problem hinzuweisen, aber dazu muss man erst einmal sehen, dass man über dieses Problem stolpern kann (was hiermit ja geschehen ist).
Ich bitte auch zu berücksichtigen, dass alle im Projekt beteiligten Personen das auf vollkommen freiwilliger Basis machen; dass die Dokumentation bereits so gut ist, wie sie ist, ist keine Selbstverständlichkeit, sondern vielen freiwilligen Helfern zu verdanken. _________________ Deine Chance beträgt 1:1000. Also musst du folgendes tun: Vergiss die 1000 und konzentriere dich auf die 1. |
|
Nach oben |
|
|
grindstone
Anmeldungsdatum: 03.10.2010 Beiträge: 1211 Wohnort: Ruhrpott
|
Verfasst am: 07.10.2015, 21:26 Titel: |
|
|
tom_dehn hat Folgendes geschrieben: | Die Umdeklarierung dieses Verhaltens zu einem Feature lassen wir mal als Flapsigkeit durchgehen (diesmal: Scherz==TRUE) | Was heißt hier Umdeklarierung? Der Compiler verhält sich exakt so, wie du als Programmierer es ihm explizit vorgeschieben hast. Und diese in FB implementierte Möglichkeit, bewußt vom erprobten Standardverhalten abzuweichen, ist eindeutig ein Feature. Daß das nicht die von dir gewünschten Resultate bringt, ist nicht die Schuld des Compilers.
Und was die Dokumentation betrifft: Dort jeden denkbaren Spezialfall zu beschreiben, ist weder möglich noch wünschenswert, weil das ganze dann viel zu umfangreich und unübersichtlich würde. Dafür gibt es ja das Forum, wo ein paar nette Jungs immer gerne weiterhelfen.
Gruß
grindstone _________________ For ein halbes Jahr wuste ich nich mahl wie man Proggramira schreibt. Jetzt bin ich einen! |
|
Nach oben |
|
|
St_W
Anmeldungsdatum: 22.07.2007 Beiträge: 949 Wohnort: Austria
|
Verfasst am: 08.10.2015, 12:56 Titel: |
|
|
Ich hab den Artikel zu EXTERN in der Referenz überarbeitet.
https://www.freebasic-portal.de/befehlsreferenz/extern-end-extern-268.html
Bisher war beschrieben dass durch die neue Namensgebung Vorteile beim Debugging / bei der Fehlersuche entstehen würden. Ich habe das zum Nebeneffekt degradiert, aber drin gelassen, obwohl ich nicht genau weiß was damit gemeint ist.
Vorgesehener Haupteinsatzzweck von EXTERN ist definitiv das Definieren einer Schnittstelle zu einer in einer anderen Programmiersprache geschriebenen Programmbibliothek. Das fehlte bisher völlig und hab ich nun ergänzt.
Den hier diskutierten Spezialfall hier habe ich nicht in die Dokumentation aufgenommen, weil ich glaube dass der EXTERN Block einfach falsch angewandt wurde.
Mich würde dazu interessieren (@tom_dehn) wie du den Extern Block verwenden wolltest. Daraus kann man dann Schlüsse ziehen und die Dokumentation verbessern, um es zukünftigen Anfängern zu erleichtern.
Die deutsche Referenz wird praktisch hauptsächlich von nemored gepflegt, der das sehr gut macht, aber eben mit sehr sehr viel Arbeit so gut wie alleine ist. Ich selber verwende meist die englischsprachige, darum bekomm ich es auch nicht wirklich mit, wenn Artikel in der deutschen Version unklar oder unvollständig sind. _________________ Aktuelle FreeBasic Builds, Projekte, Code-Snippets unter http://users.freebasic-portal.de/stw/
http://www.mv-lacken.at Musikverein Lacken (MV Lacken) |
|
Nach oben |
|
|
tom_dehn
Anmeldungsdatum: 05.10.2015 Beiträge: 30
|
Verfasst am: 08.10.2015, 17:33 Titel: |
|
|
Hi,
St_w hat was gefragt:
Zitat: |
"Mich würde dazu interessieren (@tom_dehn) wie du den Extern Block verwenden wolltest. Daraus kann man dann Schlüsse ziehen und die Dokumentation verbessern, um es zukünftigen Anfängern zu erleichtern.
|
Erst mal : Verzeihung, nach der "langen" Zeit, wo ich das alles aufgeschrieben habe, konnte ich mich ein wenig abregen
Das "warum": Luis Trenker wurde einst gefragt, warum er denn auf die Berge steige. Antwort: Weil sie da sind.
Es gibt noch mehr Gründe. Zum Beispiel könnte man auch mit FB Plugins schreiben, denke ich, etwa für Take Command, Total Commander und was weiss ich noch alles.
Weiters habe ich die Erfahrung gemacht, leider vor allem hier mit FB, daß etliche Quelltexte etc. nicht ohne weiteres kompilierbar sind. Weil irgendwelche dazu inkludierte Header-Dateien nicht mehr gültig sind, #defines und andere "#"-Kandidaten konkurrieren oder sonst was Hinderliches.
DLLs sind da weniger empfindlich. Und ich wollte halt so flexibel wie möglich sein. Mein "Demo" war und ist kein echter Code, sondern die Abstrahierung einer vielgestaltigen Funktion, die hinsichtlich ihrer Verwendung ähnlich flexibel sein sollte wie ihr einem Interpreter entlehntes Vorbild.
Sorry - noch geschraubter kriege ich es auf Anhieb nicht hin
Aber diese Abstrahierung war, im Nachhinein gesehn, ein wunderbare Fingerübung.
Zurück zu den Libs und sonstigen Hemmnissen.
Bei dem durchaus interessanten FireFly beispielsweise komme ich über irgendwelche fehlerhafte Meldungen von wegen "falsche UInt in .bi-Dateien" oder so gar nicht hinaus. Vor vielleicht 10 Tage oder so gelang mir wenigstens eine MSG-Box, aber das war es dann auch schon.
Ich möchte u.a. dazu beitrage, daß vor allem "Reinschmecker" schnelle Erfolgserlebnisse verbuchen können und ihre vielleicht fantastischen Ideen und Algorithmen schnell und effektiv in BASIC umsetzen zu können, ohne gleich die Referenz zum Compiler (nicht zur Spache, wohlgemerkt!) auswendig lernen zu müssen.
Und die Extern-Dinger, die brauch ich halt für DLLs. Das kann vermutlich ein Linuxler überhaupt nicht verstehen, weil diese Fraktion sogar das eigene OS selbst kompiliert. Und die DLLs, hoffe und plane ich, enthalten dann genau die Sachen, die man immer wieder mal braucht. Und da ich dazu neige, mich zu verzetteln, vermeide ich mit selbst zusammengestellten, in DLLs quasi gebundenen Bibliotheken, zum 117ten Mal ein DeleteString oder sonstwas Banales neu zu schreiben, bloss weil ich den Code verschusselt habe. Oder, schlimmer noch, alt bewährte Routinen aufzupolieren (tunen).
Reine Bequenlichkeit eines älteren Herrn.
Ach ja, @grindstone: Du fragst "Was heißt hier Umdeklarierung? [grinsen] Der Compiler verhält sich exakt so, wie..."
Frech heraus gesagt: Es ist mir wurscht, welcher Compiler für mich arbeitet. Ob der ein Mini-GW oder von Mikrosaft ist, meinewegen auch von Bauknecht, egal. Ich möchte auch keinen C-Code schreiben, sondern FreeBASIC. Und BASIC sollte mir angemessen sein. Idiotensicher. Buchstäblich. Und der Einwand "das ist Standard bei Windows" kann genau so gut auf die ebendort wohlbekannten "Blue Screens" angewendet werden. Was man nicht gut findet, muß man auch nicht lieben. Nicht unbedingt.
Genug gemault. Was Konstruktives.
@Nemored, der, wie st_w weiss, die "deutsche Referenz [] praktisch hauptsächlich [pflegt]", und "das sehr gut macht". Das mit dem "gut machen" kann ich bestätigen.
Wie kann ich Dir einige Kleinigkeiten in der deutschen Referenz, die ich schon mal vorbereitet habe, zukommen lassen, ohne hier im Forum TamTam zu machen? Ein paar Schreibfehler oder so, das sollte auf dem "kleinen Dienstweg" erledigt werden können.
Mir geht es vor allem auch darum, daß jemand Korrektur liest, falls ich M@ verzapfe.
Ich hab z.B. ein Demo zur Verwendung von "cdecl" (merkst Du was? passt zum Thema...) überarbeitet und so zu sagen arbeitsfähig gemacht.
Verzettelung meinerseits.
Ursprünglich war dieses Demo deklariert als "Myprintf", Quelle weiss ich nicht mehr. Falls es doch vielleicht aus der Referenz sein sollte, könnte man die alte Version ersetzen.
Es sind, glaub ich, nicht mehr als 10 Zeilen Code, die sich geändert haben. Aber ne Menge eingebettete Kommentare sind dazu gekommen.
Vielleicht lade ich es die Tage mal spasshalber hoch, ich muss das Teil wahrscheinlich noch ein bisschen austesten, um mich nicht zu blamieren.
Und, bitte scheu Dich nicht, mir konkret mal was (Überschaubares) rüberzuschieben, was dringlich erledigt weden muß. Aber bitte nix mit Grafikmodus, da habe ich eine irrationale Angst oder so was. Alles andere OK.
Dann sehen wir, ob ich wirklich eine Hilfe sein kann.
Tom
P.S.. Ich freue mich, mit Euch diskutieren zu dürfen. |
|
Nach oben |
|
|
nemored
Anmeldungsdatum: 22.02.2007 Beiträge: 4597 Wohnort: ~/
|
Verfasst am: 08.10.2015, 19:55 Titel: |
|
|
Da ich nicht unter Windows arbeite (aber mein eigenes OS compiliere ich auch nicht ), kann ich das zwar nicht genau sagen, aber es würde mich wundern, wenn du zum Erstellen von DLLs notwendigerweise auf EXTERN "Windows" zurückgreifen müsstest. Wichtig ist nur, dass das Programm weiß, wie es auf die Funktionen in der DLL zugreifen muss.
Zum Einbinden meiner Funktionsbibliotheken verwende ich ja lieber #INCLUDE; das Einbinden eines externen Quelltextes empfinde ich als deutlich einfacher als das Erstellen und Einbinden von dynamisch gelinkten Bibliotheken. Kannst es dir ja mal anschauen, ob das eine einfachere Option wäre.
Zur Referenz: Fehler kannst du selbstverständlich hier im Forum posten, du kannst mir auch gern eine PN schreiben. Inhaltliche Sachen sind im Forum vielleicht besser, weil man dann gemeinsam überlegen kann, wie man das am besten umsetzt; bei formalen Dingen ist es über PN sicher einfacher. _________________ Deine Chance beträgt 1:1000. Also musst du folgendes tun: Vergiss die 1000 und konzentriere dich auf die 1. |
|
Nach oben |
|
|
St_W
Anmeldungsdatum: 22.07.2007 Beiträge: 949 Wohnort: Austria
|
Verfasst am: 09.10.2015, 01:07 Titel: |
|
|
Erstmal vielen Dank für die ausführliche Antwort.
Vielleicht zuerst kurz der Hintergrund weswegen ich nach dem "warum" gefragt hatte: und zwar weil man Extern grundsätzlich nur braucht, wenn man von FB auf Funktionen/Objekte in einer nicht-FB Bibliothek/DLL zugreifen will. Für deinen Anwendungsfall "mit FB Plugins schreiben" wirst du es vermutlich (je nachdem wie die Plugin Schnittstelle realisiert ist) benötigen. In den meisten Anwendungsfällen benötigt man hingegen gar kein Extern, z.B. wenn sowohl Bibliothek als auch Programm in FB geschrieben sind. Ein kleines Beispiel:
In einer Bibliothek - das kann entweder eine statische (.a bzw. .lib) oder eine dynamische (.dll oder .so unter Linux) sein - wird eine Funktion implementiert:
Code: | function addieren(a as integer, b as integer) as integer EXPORT
return a+b
end function |
Im Falle einer dynamischen Bibliothek wird das "EXPORT" benötigt und mit "-dll" compiliert, im Falle einer statischen Bibliothek wird mit "-lib" compiliert und das EXPORT ist nicht notwendig.
In einem Programm wird dann diese Funktion wie folgt deklariert und verwendet (unter der Annahme, die Bibliothek wurde als "bibliothek.bas" gespeichert und entsprechend zu "bibliothek.dll" bzw. "libbibliothek.a" compiliert):
Code: | #inclib "bibliothek"
declare function addieren(a as integer, b as intger) as integer
print addieren(2,3) |
Wie man sieht, kein Export im ganzen Beispiel notwendig.
Wie nemored schon schrieb, würde ich aber für kleine Helferlein eher eine ".bi" Datei empfehlen, die du dann mit #include einbindest. Das vereinfacht die Fehlersuche und den compile-Vorgang.
Konflikte sollte es selten geben, kommen aber hier und da vor. Eine Lösung - wenn es wirklich viele Konflikte gibt oder man nichts umbenennen kann/will - ist die Funktionen in einen eigenen Namespace zu geben; z.B. angenommen die obige Bibliothek wäre einfach eine .bi, die die Funktion "addieren" definiert:
Code: | namespace bib
#include "addieren.bi"
end namespace
'Zugriff dann via:
bib.addieren(2,3) |
Bzgl. FireFly habe ich leider keine Erfahrung - ich nutze hauptsächlich FbEdit. Um komfortable Editoren ist es aber derzeit leider allgemein schlecht bestellt. Keine der vorhandenen bietet wirklich einfache Möglichkeiten eine grafische Oberfläche zusammenzustellen, wobei FireFly diesbzgl. wohl noch die beste (oder das geringste Übel?) ist.
Im Allgemeinen scheint sich FB derzeit weg vom ursprünglichen BASIC Gedanken (einfach, "Idiotensicher") hin zu einem C++ mit ein wenig anderer Syntax zu entwickeln; was natürlich nicht unbedingt gut ist. _________________ Aktuelle FreeBasic Builds, Projekte, Code-Snippets unter http://users.freebasic-portal.de/stw/
http://www.mv-lacken.at Musikverein Lacken (MV Lacken) |
|
Nach oben |
|
|
RWK
Anmeldungsdatum: 04.07.2011 Beiträge: 44
|
Verfasst am: 09.10.2015, 13:25 Titel: |
|
|
St_W hat Folgendes geschrieben: |
Bzgl. FireFly habe ich leider keine Erfahrung - ich nutze hauptsächlich FbEdit. Um komfortable Editoren ist es aber derzeit leider allgemein schlecht bestellt. Keine der vorhandenen bietet wirklich einfache Möglichkeiten eine grafische Oberfläche zusammenzustellen, wobei FireFly diesbzgl. wohl noch die beste (oder das geringste Übel?) ist.
|
Hallo zusammen,
ja vielleicht sollten wir hier in der Tat mehr im deutschen Forum machen.
Bezüglich FireFly kann ich nun wirklich nicht sagen, das das Ding nicht ordentlich läuft. Wenn der Paul da noch ein VisualGrid eingebaut hätte wäre es noch besser. (ich habe aber munkeln hören das er an sowas bastelt incl. SQLite unterbau ) Aber Fehler erhalte ich da kaum. Und obwohl ich für mein Lauf Programm dort SQLite und TSNE mit eingebaut habe. Wir können ja mal Beispiele zusammentragen.
Ansonsten bin ich aber für FLTK. das Gefällt mir; man kann aber eben das Interface nicht visuell zusammenschieben, Properties belegen und die einzelnen Widgets dann visuell den Ecken oder Top bzw. Bottem zuordnen damit sich die Widgets bei Größenveränderung des Fensters ordentlich verhalten...das wäre was. Joshy würde jetzt sagen....jawohl das geht..........im Code
So jetzt eine Woche Urlaub
Grüße
Rainer |
|
Nach oben |
|
|
grindstone
Anmeldungsdatum: 03.10.2010 Beiträge: 1211 Wohnort: Ruhrpott
|
Verfasst am: 09.10.2015, 15:00 Titel: |
|
|
@St_W:
Zitat: | In den meisten Anwendungsfällen benötigt man hingegen gar kein Extern, z.B. wenn sowohl Bibliothek als auch Programm in FB geschrieben sind. |
Die Probleme, die tom_dehn hat, entstehen durch das Überladen der Funktionen. Dadurch bekommen intern mehrere Funktionen denselben Bezeichner und die Compilierung bricht mit einer Fehlermeldung ab. Einen anderen Workaround als die Verwendung von Dummyparametern sehe ich da im Moment nicht. Diese Problematik wäre vielleicht doch einen feature request wert (und eventuell auch einen Hinweis in der Referenz, daß überladene Funktionen in Bibliotheken unterschiedlich lange Parameterlisten haben müssen).
@tom_dehn:
Zitat: | Frech heraus gesagt: Es ist mir wurscht, welcher Compiler für mich arbeitet. Ob der ein Mini-GW oder von Mikrosaft ist, meinewegen auch von Bauknecht, egal. Ich möchte auch keinen C-Code schreiben, sondern FreeBASIC. Und BASIC sollte mir angemessen sein. Idiotensicher. Buchstäblich. | Dazu fällt mir ganz spontan ein Spruch ein: "Es ist unmöglich, etwas narrensicher zu machen. Dazu sind die Narren viel zu einfallsreich." Die einzige Möglichkeit, solche Probleme sicher zu vermeiden, wäre, Anweisungen wie EXTERN, CDECL oder EXPORT aus FB zu entfernen - und es damit der Fähigkeit zu berauben, Bibliotheken von anderen Programmiersprachen zu verwenden.
Zitat: | Zum Beispiel könnte man auch mit FB Plugins schreiben, denke ich, etwa für Take Command, Total Commander und was weiss ich noch alles. | Was Plugins betrifft, kann ich dir in aller (Un-)Bescheidenheit ein funktionierendes Beispiel nennen, das du dir einmal ansehen kannst:
https://www.freebasic-portal.de/code-beispiele/multimedia/winamp-general-purpose-plugin-274.html
(Ironie der Geschichte: Ich hatte mich entschlossen, ein Plugin zur Steuerung von Winamp mit einem Gamepad zu schreiben, und zwar in FB, weil ich keine Lust hatte, dafür extra C zu lernen. Dumm nur, daß das Winamp SDK in C geschrieben ist. Auf diese Weise habe ich dann (so ganz nebenbei und gezwungenermaßen) doch noch C gelernt...)
@RWK:
Eine einfach zu bedienende Implementierung von FireFly wäre klasse! Dann könnte ich meinen Konsolenprogrammen endlich mal eine zeitgemäße Oberfläche spendieren. Obwohl es erstaunlich ist, was man in dieser Beziehung auch aus dem Konsolenfenster herausholen kann.
Gruß
grindstone _________________ For ein halbes Jahr wuste ich nich mahl wie man Proggramira schreibt. Jetzt bin ich einen! |
|
Nach oben |
|
|
St_W
Anmeldungsdatum: 22.07.2007 Beiträge: 949 Wohnort: Austria
|
Verfasst am: 09.10.2015, 17:37 Titel: |
|
|
@grindstone:
grindstone hat Folgendes geschrieben: | Die Probleme, die tom_dehn hat, entstehen durch das Überladen der Funktionen. Dadurch bekommen intern mehrere Funktionen denselben Bezeichner und die Compilierung bricht mit einer Fehlermeldung ab. |
Danke für die Erklärung, aber mir war schon völlig klar was das Problem ist
grindstone hat Folgendes geschrieben: | Einen anderen Workaround als die Verwendung von Dummyparametern sehe ich da im Moment nicht. Diese Problematik wäre vielleicht doch einen feature request wert (und eventuell auch einen Hinweis in der Referenz, daß überladene Funktionen in Bibliotheken unterschiedlich lange Parameterlisten haben müssen). |
Doch es gibt eine Lösung, die weder "Workaround" noch Frickellösung ist, sondern schlicht die normale, vorhergesehene Anwendung: Und zwar, wie ich vorhin bereits erwähnt hatte, ohne "Export".
Der FBC generiert für überladene Methoden automatisch passende interne Namen (nach dem C++ (gcc) Schema), wenn man ihn nicht entsprechend anders anweist. Und genau hier liegt das Problem. Mit Export "C"/"Windows"/"Windows-MS" sagst du dem Compiler dass er Methoden entsprechend benennen soll, was natürlich zu Konflikten führt. Das einzige Namensschema das für überladene Methoden gedacht ist und funktioniert ist Export "C++". Und wenn man nicht mit einer C++ Bibliothek zusammenarbeitet lässt man das Export einfach weg - und zwar nicht aus Faulheit, sondern weils besser ist wenns nicht angegeben wird und der Compiler selbst das passende Namensschema wählt.
Hier nochmal ein kleines Beispiel:
Code: | Function fn overload (a as integer) as integer export
Return a+1
End Function
Function fn overload (a as string) as integer export
Return val(a)+1
End Function
Function fn2 (a as integer) as integer export
return a+1
End Function |
Die internen Namen entsprechen (natürlich auch wenn man die Funktionen nur Deklarieren, nicht implementieren würde) unter Windows:
Code: | FN2@4
_Z2FNR8FBSTRING@4
_Z2FNi@4 |
Wie man sieht wird für die überladenen Methoden automatisch das C++(gcc) Schema verwendet, für alle "normalen" Methoden das Standard Schema.
Das Problem ist hier also weder ein Compiler Bug noch ein fehlendes Feature, sondern einfach eine falsche Anwendung. _________________ Aktuelle FreeBasic Builds, Projekte, Code-Snippets unter http://users.freebasic-portal.de/stw/
http://www.mv-lacken.at Musikverein Lacken (MV Lacken) |
|
Nach oben |
|
|
grindstone
Anmeldungsdatum: 03.10.2010 Beiträge: 1211 Wohnort: Ruhrpott
|
Verfasst am: 09.10.2015, 18:07 Titel: |
|
|
AUA!!
Beides ganz ohne "Extern" war wohl die einzige Kombination, die ich nicht ausprobiert habe.
Das hier als overload_lib mit -lib compiliert... Code: | Function fn OverLoad (s1 As String, n1 As Single) As String
Print s1,n1
Return "s1,n1"
End Function
Function fn (s1 As String ) As String
Print s1
Return "s1"
End Function
Function fn (n1 As Single, s1 As String ) As String
Print n1,s1
Return "n1,s1"
End Function
Function fn (n1 As Single ) As String
Print n1
Return "n1"
End Function
Function fn () As String 'Export
Print "?"
Return "?"
End Function |
...und das hier als Hauptprogramm Code: | #Inclib "overload_lib"
Declare Function fn OverLoad (s1 As String, n1 As Single) As String
Declare Function fn (s1 As String ) As String
Declare Function fn (n1 As Single, s1 As String) As String
Declare Function fn ( n1 As Single) As String
Declare Function fn () As String
'' MAIN()
Print fn ("str",3.14)
fn ("str",3.14)
fn
Print fn()
Sleep | funktioniert einwandfrei.
Obwohl (@tom_dehn) ich es sinnvoller finde, innerhalb von FB solche Programmteile per .bi - Datei einzubinden.
Gruß
grindstone
EDIT: Mein Fehler war noch viel blöder: Ich habe die Bibliothek irgendwann in overload_lib2 umbenannt und vergessen, den Namen im Hauptprogramm zu ändern. Da kann ich natürlich lange rumprobieren... _________________ For ein halbes Jahr wuste ich nich mahl wie man Proggramira schreibt. Jetzt bin ich einen! |
|
Nach oben |
|
|
tom_dehn
Anmeldungsdatum: 05.10.2015 Beiträge: 30
|
Verfasst am: 11.10.2015, 22:07 Titel: Thread gelöst?? |
|
|
Hi,
ich habe es _definitiv_ begriffen, was ich nicht hätte machen sollen. Aber ich bin nicht von alleine auf die (Schaps-)Idee gekommen, sondern hab das irgendwo unter "so baue ich eine DLL für Windows" abgekupfert. Und war erst mal froh, daß es anfangs recht klappte.
Jetzt mit Euren Ratschlägen geht es astrein.
Mittlerweile bin ich sogar schon ein wenig zur Coden gekommen
Herzlichen Dank für die Tipps und Erklärungen. Auch wenn man die unter FBC/64/OS=WIN nur unter erschwerten Bedingungen nutzen kann.
A pro pos:
grindstone antwortet @RWK:
Eine einfach zu bedienende Implementierung von FireFly wäre klasse! Dann könnte ich meinen Konsolenprogrammen endlich mal eine zeitgemäße Oberfläche spendieren. Obwohl es erstaunlich ist, was man in dieser Beziehung auch aus dem Konsolenfenster herausholen kann.
Denke ich auch. Wenigstens eine klitzekleine Demo mit irgendwas was auch für die "B"s in "B"ASIC ausprobierbar ist...
Aber das wäre wohl ein anderer Thread.
Tom
[/quote] |
|
Nach oben |
|
|
St_W
Anmeldungsdatum: 22.07.2007 Beiträge: 949 Wohnort: Austria
|
Verfasst am: 12.10.2015, 01:14 Titel: Re: Thread gelöst?? |
|
|
tom_dehn hat Folgendes geschrieben: | ich habe es _definitiv_ begriffen, was ich nicht hätte machen sollen. |
Wunderbar. Es sollte übrigens nicht als Belehrung / "Kritik an einem Fehler" rüberkommen - falls es das ist, sorry, war nicht so gedacht. Einsteiger machen nunmal Fehler - sonst wäre ja jeder sofort ein Profi. Das ist auch gut so, denn daraus lernt man (hoffentlich ).
tom_dehn hat Folgendes geschrieben: | Aber ich bin nicht von alleine auf die (Schaps-)Idee gekommen, sondern hab das irgendwo unter "so baue ich eine DLL für Windows" abgekupfert. Und war erst mal froh, daß es anfangs recht klappte. |
Wär interessant, wo du das gesehen hast. Denn wenn es in unserem Einflussbereich liegt, würden wir das natürlich gern ausbessern.
tom_dehn hat Folgendes geschrieben: | Herzlichen Dank für die Tipps und Erklärungen. |
Bitte gerne und wie gesagt sorry wenn es schon etwas zuviel des Guten war.
tom_dehn hat Folgendes geschrieben: | Auch wenn man die unter FBC/64/OS=WIN nur unter erschwerten Bedingungen nutzen kann. |
Ich hab gesehen du hast dazu eh schon einen eigenen Thread aufgemacht, damit man sich die Probleme im Detail anschaun und hoffentlich lösen kann. _________________ Aktuelle FreeBasic Builds, Projekte, Code-Snippets unter http://users.freebasic-portal.de/stw/
http://www.mv-lacken.at Musikverein Lacken (MV Lacken) |
|
Nach oben |
|
|
|
|
Du kannst keine Beiträge in dieses Forum schreiben. Du kannst auf Beiträge in diesem Forum nicht antworten. Du kannst deine Beiträge in diesem Forum nicht bearbeiten. Du kannst deine Beiträge in diesem Forum nicht löschen. Du kannst an Umfragen in diesem Forum nicht mitmachen.
|
|