Das deutsche QBasic- und FreeBASIC-Forum Foren-Übersicht Das deutsche QBasic- und FreeBASIC-Forum
Für euch erreichbar unter qb-forum.de, fb-forum.de und freebasic-forum.de!
 
FAQFAQ   SuchenSuchen   MitgliederlisteMitgliederliste   BenutzergruppenBenutzergruppen  RegistrierenRegistrieren
ProfilProfil   Einloggen, um private Nachrichten zu lesenEinloggen, um private Nachrichten zu lesen   LoginLogin
Zur Begleitseite des Forums / Chat / Impressum
Aktueller Forenpartner:

Reproduzierbarer Bug bei Funktionen mit overload

 
Neues Thema eröffnen   Neue Antwort erstellen    Das deutsche QBasic- und FreeBASIC-Forum Foren-Übersicht -> Allgemeine Fragen zu FreeBASIC.
Vorheriges Thema anzeigen :: Nächstes Thema anzeigen  
Autor Nachricht
tom_dehn



Anmeldungsdatum: 05.10.2015
Beiträge: 30

BeitragVerfasst am: 05.10.2015, 23:15    Titel: Reproduzierbarer Bug bei Funktionen mit overload Antworten mit Zitat

"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 traurig




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
Benutzer-Profile anzeigen Private Nachricht senden
St_W



Anmeldungsdatum: 22.07.2007
Beiträge: 949
Wohnort: Austria

BeitragVerfasst am: 06.10.2015, 12:45    Titel: Antworten mit Zitat

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
Benutzer-Profile anzeigen Private Nachricht senden
grindstone



Anmeldungsdatum: 03.10.2010
Beiträge: 1211
Wohnort: Ruhrpott

BeitragVerfasst am: 06.10.2015, 13:03    Titel: Antworten mit Zitat

Hallo tom_dehn und willkommen im Forum lächeln

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" zwinkern

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. lächeln
_________________
For ein halbes Jahr wuste ich nich mahl wie man Proggramira schreibt. Jetzt bin ich einen!
Nach oben
Benutzer-Profile anzeigen Private Nachricht senden E-Mail senden
tom_dehn



Anmeldungsdatum: 05.10.2015
Beiträge: 30

BeitragVerfasst am: 06.10.2015, 21:24    Titel: Antworten mit Zitat

Hi, St_W und Grindstone,

vielen Dank für Eure Antworten. Und den Willkommensgruss lächeln

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










lächeln lächeln
Nach oben
Benutzer-Profile anzeigen Private Nachricht senden
nemored



Anmeldungsdatum: 22.02.2007
Beiträge: 4597
Wohnort: ~/

BeitragVerfasst am: 06.10.2015, 22:10    Titel: Antworten mit Zitat

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. lächeln
_________________
Deine Chance beträgt 1:1000. Also musst du folgendes tun: Vergiss die 1000 und konzentriere dich auf die 1.
Nach oben
Benutzer-Profile anzeigen Private Nachricht senden
grindstone



Anmeldungsdatum: 03.10.2010
Beiträge: 1211
Wohnort: Ruhrpott

BeitragVerfasst am: 07.10.2015, 21:26    Titel: Antworten mit Zitat

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? grinsen 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. zwinkern

Gruß
grindstone
_________________
For ein halbes Jahr wuste ich nich mahl wie man Proggramira schreibt. Jetzt bin ich einen!
Nach oben
Benutzer-Profile anzeigen Private Nachricht senden E-Mail senden
St_W



Anmeldungsdatum: 22.07.2007
Beiträge: 949
Wohnort: Austria

BeitragVerfasst am: 08.10.2015, 12:56    Titel: Antworten mit Zitat

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
Benutzer-Profile anzeigen Private Nachricht senden
tom_dehn



Anmeldungsdatum: 05.10.2015
Beiträge: 30

BeitragVerfasst am: 08.10.2015, 17:33    Titel: Antworten mit Zitat

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 lächeln
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 zwinkern
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
Benutzer-Profile anzeigen Private Nachricht senden
nemored



Anmeldungsdatum: 22.02.2007
Beiträge: 4597
Wohnort: ~/

BeitragVerfasst am: 08.10.2015, 19:55    Titel: Antworten mit Zitat

Da ich nicht unter Windows arbeite (aber mein eigenes OS compiliere ich auch nicht lachen ), 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. lächeln
_________________
Deine Chance beträgt 1:1000. Also musst du folgendes tun: Vergiss die 1000 und konzentriere dich auf die 1.
Nach oben
Benutzer-Profile anzeigen Private Nachricht senden
St_W



Anmeldungsdatum: 22.07.2007
Beiträge: 949
Wohnort: Austria

BeitragVerfasst am: 09.10.2015, 01:07    Titel: Antworten mit Zitat

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
Benutzer-Profile anzeigen Private Nachricht senden
RWK



Anmeldungsdatum: 04.07.2011
Beiträge: 44

BeitragVerfasst am: 09.10.2015, 13:25    Titel: Antworten mit Zitat

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 lächeln ) 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 lächeln


So jetzt eine Woche Urlaub grinsen

Grüße
Rainer
Nach oben
Benutzer-Profile anzeigen Private Nachricht senden
grindstone



Anmeldungsdatum: 03.10.2010
Beiträge: 1211
Wohnort: Ruhrpott

BeitragVerfasst am: 09.10.2015, 15:00    Titel: Antworten mit Zitat

@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." grinsen 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...) grinsen

@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
Benutzer-Profile anzeigen Private Nachricht senden E-Mail senden
St_W



Anmeldungsdatum: 22.07.2007
Beiträge: 949
Wohnort: Austria

BeitragVerfasst am: 09.10.2015, 17:37    Titel: Antworten mit Zitat

@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 zwinkern

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
Benutzer-Profile anzeigen Private Nachricht senden
grindstone



Anmeldungsdatum: 03.10.2010
Beiträge: 1211
Wohnort: Ruhrpott

BeitragVerfasst am: 09.10.2015, 18:07    Titel: Antworten mit Zitat

AUA!! mit dem Kopf durch die Mauer wollen

Beides ganz ohne "Extern" war wohl die einzige Kombination, die ich nicht ausprobiert habe. peinlich

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. Daumen rauf!

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
Benutzer-Profile anzeigen Private Nachricht senden E-Mail senden
tom_dehn



Anmeldungsdatum: 05.10.2015
Beiträge: 30

BeitragVerfasst am: 11.10.2015, 22:07    Titel: Thread gelöst?? Antworten mit Zitat

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 lächeln

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
Benutzer-Profile anzeigen Private Nachricht senden
St_W



Anmeldungsdatum: 22.07.2007
Beiträge: 949
Wohnort: Austria

BeitragVerfasst am: 12.10.2015, 01:14    Titel: Re: Thread gelöst?? Antworten mit Zitat

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 zwinkern ).

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
Benutzer-Profile anzeigen Private Nachricht senden
Beiträge der letzten Zeit anzeigen:   
Neues Thema eröffnen   Neue Antwort erstellen    Das deutsche QBasic- und FreeBASIC-Forum Foren-Übersicht -> Allgemeine Fragen zu FreeBASIC. Alle Zeiten sind GMT + 1 Stunde
Seite 1 von 1

 
Gehe zu:  
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.

 Impressum :: Datenschutz