Vorheriges Thema anzeigen :: Nächstes Thema anzeigen |
Autor |
Nachricht |
grindstone
Anmeldungsdatum: 03.10.2010 Beiträge: 1278 Wohnort: Ruhrpott
|
Verfasst am: 13.01.2015, 20:50 Titel: Problem mit LIB: undefined reference |
|
|
Hallo!
Wenn ich das Beispiel zum Schlüsselwort LIB in der FB-Befehlsreferenz ausprobiere (übertragen mit Copy&Paste, also keine Tippfehler), bekomme ich die Fehlermeldung:
Code: | main.o:fake:(.text+0x3b): undefined reference to `GetValue@0' |
Woran liegt's ?
Gruß
grindstone _________________ For ein halbes Jahr wuste ich nich mahl wie man Proggramira schreibt. Jetzt bin ich einen! |
|
Nach oben |
|
 |
nemored

Anmeldungsdatum: 22.02.2007 Beiträge: 4700 Wohnort: ~/
|
Verfasst am: 13.01.2015, 23:09 Titel: |
|
|
Die mydll.dll hast du erstellt? Ich habe gerade etwas Probleme, das Beispiel in der Referenz zu testen, weil ich keine mydll.so (bin ja unter Linux) erstellen kann; ich weiß aber nicht, ob ich da was falsch mache oder ob es an einem fehlerhaften Code für die DLL liegt. _________________ 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: 1278 Wohnort: Ruhrpott
|
Verfasst am: 14.01.2015, 11:06 Titel: |
|
|
nemored hat Folgendes geschrieben: | Die mydll.dll hast du erstellt? | Ja, habe ich.
Ich habe ein wenig herumprobiert. Das Beispiel funktioniert, wenn die Zeile Code: | Declare Function GetValue Lib "mydll" ALIAS "GetValue" As Integer | in beiden Programmteilen, also sowohl in der .dll als auch im aufrufenden Programm steht.
Die Logik dieser Vorgehensweise erschließt sich mir allerdings (noch) nicht.
Gibt es eine Möglichkeit, mir Prozeduren aus einem ausführbaren Programm (also .exe, nicht .dll) "auszuleihen"?
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: 956 Wohnort: Austria
|
Verfasst am: 14.01.2015, 12:47 Titel: |
|
|
Wenn du dir die erstellte DLL mit depends angeschaut hättest, wüsstest du warum es nicht funktioniert bzw. was der Fehler ist.
Wenn du auf der importierenden Seite (EXE) einen Alias angibst, der vom Standard-Namen abweicht, musst du natürlich auch auf der exportierenden Seite (DLL) denselben Alias angeben, damit der Name übereinstimmt.
Dies kannst du entweder über ein zusätzliches Declare, wie von dir erwähnt, oder einfach durch Hinzufügen von >>Alias "GetValue"<< zur Methodendefinition lösen: Code: | Public Function GetValue Alias "GetValue" () As Integer Export
Function = &h1234
End Function |
Anstatt dem antiquierten "Function = Rückgabewert" Konstrukt verwendet man übrigens besser die aktuellere Syntax "Return Rückgabewert".
Eine EXE kannst du meines Wissens nach nicht so laden, als wäre es eine DLL.
Allerdings hab ich hier was gefunden, das mögliche Hacks evaluiert, mit denen sowas möglich sein könnte: http://sandsprite.com/CodeStuff/Using_an_exe_as_a_dll.html
Aber, um es nochmal zu betonen, das sind mehr oder weniger üble Hacks, die man - wenns irgendwie geht - vermeiden sollte. Wieso willst du sowas überhaupt machen?
In der Praxis ist es oft eher umgekehrt: man hat alles in einer DLL und eine kleine zusätzliche EXE macht nix anderes als die DLL zu laden und das dort enthaltene Programm zu starten. _________________ 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: 1278 Wohnort: Ruhrpott
|
Verfasst am: 14.01.2015, 13:49 Titel: |
|
|
Hallo St_W,
vielen Dank für die schnelle Hilfe . Ja, mit dem zusätzliche "Alias" funktioniert die Sache. Vielleicht sollte man das Beispiel in der Referenz entsprechend nachbessern.
Und das mit dem Nachladen aus einer .exe werde ich -zumindest im Augenblick- erst mal lassen, da komme ich tatsächlich in Teufels Küche. Ich habe mit ein paar kleinen Programmschnipseln herumexperimentiert, die Sub macht alles mögliche, nur nicht das, was sie soll.
Zitat: | Wieso willst du sowas überhaupt machen?
|
Eines meiner Projekte ist Colochessum, und zu diesem Programm gibt es eine Pseudo-Engine (human interface), mit deren Hilfe man Züge per Maus eingeben, sprich Schach spielen kann. Beide Programme haben etliche identische Prozeduren, eigentlich die klassische Anwendung für eine .dll, aber ich möchte die Anzahl der benötigten Dateien möglichst klein halten. Daher wäre es praktisch, wenn sich das human interface die entsprechenden Prozeduren direkt aus der Colochessum - Programmdatei laden könnte.
Wirklich existenziell wichtig ist diese Möglichkeit nicht, es wäre nur ein nettes Feature.
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: 956 Wohnort: Austria
|
|
Nach oben |
|
 |
volta
Anmeldungsdatum: 04.05.2005 Beiträge: 1876 Wohnort: D59192
|
Verfasst am: 14.01.2015, 20:57 Titel: |
|
|
Hi,
auch aus einer EXE kann man Functions/Subs aufrufen wenn sie als EXPORT gekennzeichnet sind.
Beispiel: myexe.bas
Code: | ' myexe.bas: compilieren mit
' fbc fbc -s console myexe.bas
' zur myexe.exe
Function GetValue Alias "GetValue" As Integer Export
Function = &h1234
End Function |
Code: | Dim GetValue As Function() As Integer
Dim As Any Ptr library = DylibLoad("myexe.exe")
If library Then
GetValue = DyLibSymbol(library,"GetValue")
If GetValue Then
Print "GetValue = &h"; Hex(GetValue())
EndIf
DylibFree library
EndIf
Sleep
|
_________________ Warnung an Choleriker:
Dieser Beitrag kann Spuren von Ironie & Sarkasmus enthalten.
Zu Risiken & Nebenwirkungen fragen Sie Ihren Therapeuten oder Psychiater. |
|
Nach oben |
|
 |
St_W

Anmeldungsdatum: 22.07.2007 Beiträge: 956 Wohnort: Austria
|
Verfasst am: 15.01.2015, 00:29 Titel: |
|
|
Interessant .. wusste ich nicht, dass das eh so einfach auf die selbe Art und Weise funktioniert.
In der Dokumentation zu LoadLibrary (das WinAPI Äquivalent zu FB's DyLibLoad) hab ich zwar vorhin auch gelesen, dass explizit auch executables geladen werden können; als Beispiel wurden dort jedoch nur der Zugriff auf Ressourcen genannt.
Die vorhin von mir verlinkte Seite behandelt dann wohl etwas anderes/spezifische Probleme?! - ich habs mir ehrlich gesagt nicht so genau angeschaut, sondern nur überflogen. _________________ 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: 1278 Wohnort: Ruhrpott
|
Verfasst am: 15.01.2015, 12:20 Titel: |
|
|
St_W hat Folgendes geschrieben: | wusste ich nicht, dass das eh so einfach auf die selbe Art und Weise funktioniert. |
Tut es auch nicht (leider ). Ein einfacher Print - Befehl in der Function führt zum Programmabsturz. Code: | ' myexe.bas: compilieren mit
' fbc fbc -s console myexe.bas
' zur myexe.exe
Function GetValue Alias "GetValue" As Integer Export
Print "Hallo Welt"
Function = &h1234
End Function | Das gleiche passiert, wenn der Rückgabewert kein Integer, sondern ein String ist.
Die Verwendung der entsprechenden WinAPI-Funktionen (LoadLibrary und GetProcAddress, zusammen mit Cdecl in der Function) bringt das gleiche Ergebnis.
Ist wohl doch etwas komplizierter, das alles.
Gruß
grindstone _________________ For ein halbes Jahr wuste ich nich mahl wie man Proggramira schreibt. Jetzt bin ich einen! |
|
Nach oben |
|
 |
Eternal_pain

Anmeldungsdatum: 08.08.2006 Beiträge: 1783 Wohnort: BW/KA
|
Verfasst am: 16.01.2015, 09:37 Titel: |
|
|
Ich rate da einfach mal drauf los...
ich vermute hier das bei Ausgabe-Befehlen (Print, Line und co) hier der Context fehlt der evtl zwar in deinem eigentlichen Programm gegeben sein mag aber nicht in der lib/exe... daher haben Libs mit Ausgabe-Befehlen oft auch eine initialisierung (hier reicht evtl ein screenres?) Die ausgabe müsste dann aber auch wieder über lib erfolgen... Strings und co dürfte wohl das selbe sein da ich meine das du nicht so ohne weiteres auf speicher von deinem Programm auf den eines anderen zugreifen kannst... String/ZString/Allocate, so müsstest für die zugriffe glaube noch 'schnittstellen' basteln... einfache variablen/Berechnungen sollten so aber eigentlich funktionieren _________________
 |
|
Nach oben |
|
 |
volta
Anmeldungsdatum: 04.05.2005 Beiträge: 1876 Wohnort: D59192
|
Verfasst am: 16.01.2015, 11:41 Titel: |
|
|
Hi, Zitat: | Ist wohl doch etwas komplizierter, das alles. |
Na ja, man kann halt nicht alles haben!
Es gibt aber eine innovative Lösung (nicht ernsthaft)!
Code: | ' myexe.bas: compilieren mit
' fbc fbc -s console myexe.bas
' zur myexe.exe
Function GetValue Alias "GetValue"(x() As integer) As Integer Export
x(0) = Cvl("Hall")
x(1) = Cvl("o We")
x(2) = CVl("lt ")
Function = 1
End Function |
Code: | Dim GetValue As Function (x() As Integer) As Integer
Dim As Any Ptr library = DylibLoad("myexe.exe")
If library Then
GetValue = DylibSymbol(library, "GetValue")
If GetValue Then
Dim z(2) As Integer
GetValue(z())
Print MKL(z(0)); MKL(z(1)); MKL(z(2))
EndIf
DylibFree library
EndIf
Sleep |
_________________ Warnung an Choleriker:
Dieser Beitrag kann Spuren von Ironie & Sarkasmus enthalten.
Zu Risiken & Nebenwirkungen fragen Sie Ihren Therapeuten oder Psychiater. |
|
Nach oben |
|
 |
grindstone
Anmeldungsdatum: 03.10.2010 Beiträge: 1278 Wohnort: Ruhrpott
|
Verfasst am: 16.01.2015, 12:29 Titel: |
|
|
volta hat Folgendes geschrieben: | Na ja, man kann halt nicht alles hben! | Aber einen Versuch war's wert.
Zitat: | Es gibt aber eine innovative Lösung (nicht ernsthaft)! grinsen | Immerhin: Es funktioniert.
Eternal_pain hat Folgendes geschrieben: | Ich rate da einfach mal drauf los... | Soweit ich das verstanden habe, was im Link von St_W steht, bekommt jede Prozedur in einer .dll vom Compiler einige zusätzliche Infos mit, die das Einbinden zur Laufzeit erst ermöglichen.
Übrigens: Das Einbinden einer als .dll Compilierten ausführbaren Datei hat einen anderen lustigen Nebeneffekt:
Code: | ' myexe.bas: compilieren mit
' fbc -dll myexe.bas
' zur myexe.dll
Function GetValue Alias "GetValue"() As String Export
Print "Hallo Welt"
Function = "Ist da jemand?"
End Function
Print "Ich bin gestartet"
Print GetValue |
Code: | Dim GetValue As Function () As String
Dim As Any Ptr library = DylibLoad("myexe.dll")
Sleep
If library Then
GetValue = DylibSymbol(library, "GetValue")
If GetValue Then
Print GetValue()
EndIf
DylibFree library
EndIf
Sleep | Nur, wie ich diese pseudo-dll dann als "normales" Programm gestartet kriege, habe ich noch nicht herausgefunden.
Gruß
grindstone _________________ For ein halbes Jahr wuste ich nich mahl wie man Proggramira schreibt. Jetzt bin ich einen! |
|
Nach oben |
|
 |
Jojo alter Rang

Anmeldungsdatum: 12.02.2005 Beiträge: 9736 Wohnort: Neben der Festplatte
|
Verfasst am: 16.01.2015, 13:19 Titel: |
|
|
Eternal_pain hat Folgendes geschrieben: | Die ausgabe müsste dann aber auch wieder über lib erfolgen... Strings und co dürfte wohl das selbe sein da ich meine das du nicht so ohne weiteres auf speicher von deinem Programm auf den eines anderen zugreifen kannst... |
Zwischen Prozessen ist das nicht ohne Weiteres möglich ja, aber wenn man eine DLL (und wenn's nur eine EXE ist, das macht keinne Unterschied) in ein anderen Programm lädt, landen die beide im selben Prozess, d.h. solange dieselbe Runtime-Bibliothek (sprich FB-VErsion) für die Strings in beiden Teilen verwendet wurde, sollten hier keine Kompatiblitätsprobleme auftreten. _________________ » Die Mathematik wurde geschaffen, um Probleme zu lösen, die es nicht gäbe, wenn die Mathematik nicht erschaffen worden wäre.
 |
|
Nach oben |
|
 |
|