 |
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 |
ebrady
Anmeldungsdatum: 06.07.2005 Beiträge: 45
|
Verfasst am: 29.10.2006, 21:09 Titel: Problem mit dynamischem Linken (?) |
|
|
Hallo!
Ich will zig verschiedene DLLs zur Laufzeit laden und wieder rausschmeissen. Deshalb speichere ich sie in einem Array modul().
FB 0.16b kompiliert das zwar, aber nur unter dem Vorbehalt
"Passing pointer to scalar, at parameter 1 of DYLIBFREE"
Was soll ich davon halten?
Code: |
declare function ModulLaden(nummer,typ) as string
declare function ModulAbwerfen(nummer,typ) as string
dim shared modul(1 to 100,1 to 3) as sub
FUNCTION ModulLaden(nummer,typ) as string
dim check as integer
dim datei as string
dim typstr as string
dim modulbez as string
select case typ
case 1
typstr="FB"
case 2
typstr="SW"
case 3
typstr="FP"
end select
datei="/"+typstr+"/"+typstr+"_"+str(nummer)+".dll"
check=dylibload (datei)
select case check
case 0
return ("Datei nicht gefunden: "+datei)
case else
modulbez=typstr+"_"+str(nummer)
modul(nummer,typ)=dylibsymbol(check,modulbez)
if modul(nummer,typ)=0 then return ("Modul nicht gefunden: "+modulbez)
end select
return "geladen"
END FUNCTION
FUNCTION ModulAbwerfen(nummer,typ) as string
dylibfree modul(nummer,typ)
return "abgeworfen"
END FUNCTION |
Zuletzt bearbeitet von ebrady am 30.10.2006, 02:44, insgesamt 2-mal bearbeitet |
|
Nach oben |
|
 |
ebrady
Anmeldungsdatum: 06.07.2005 Beiträge: 45
|
Verfasst am: 29.10.2006, 21:37 Titel: |
|
|
OK, war wohl fehlerhaft. Ich muss über den Handle freigeben.
Code: | declare function ModulLaden(nummer,typ) as string
declare function ModulAbwerfen(nummer,typ) as string
dim shared modul(1 to 100,1 to 3) as sub
dim shared handle as integer
FUNCTION ModulLaden(nummer,typ) as string
dim datei as string
dim typstr as string
dim modulbez as string
select case typ
case 1
typstr="FB"
case 2
typstr="SW"
case 3
typstr="FP"
end select
datei="/"+typstr+"/"+typstr+"_"+str(nummer)+".dll"
handle=dylibload (datei)
select case handle
case 0
return ("Datei nicht gefunden: "+datei)
case else
modulbez=typstr+"_"+str(nummer)
modul(nummer,typ)=dylibsymbol(handle,modulbez)
if modul(nummer,typ)=0 then return ("Modul nicht gefunden: "+modulbez)
end select
return "geladen"
END FUNCTION
FUNCTION ModulAbwerfen(nummer,typ) as string
dylibfree handle
return "abgeworfen"
END FUNCTION |
So müsste es doch funktionieren? |
|
Nach oben |
|
 |
ebrady
Anmeldungsdatum: 06.07.2005 Beiträge: 45
|
Verfasst am: 30.10.2006, 02:44 Titel: |
|
|
Jetzt bin ich wirklich festgefahren. Alles haut soweit hin, die dlls werden eingebunden. Aber irgendwie werden sie nicht richtig ausgeführt. Ehrlich gesagt hab ich aber wenig Hoffnung, dass mir jemand helfen kann.
Code: | print modul(zelle(i,3),1) |
gibt einen Wert um 85 Millionen zurück, obwohl eigentlich nur 1 oder 0 kommen sollte.
Ganz seltsam wird's, wenn ich stattdessen das versuche:
Code: | x=modul(zelle(i,3),1)) |
-> "implicit conversion" ???
x und Funktion sind natürlich beide Integer
Ich weiss echt nicht mehr weiter! |
|
Nach oben |
|
 |
terminate
Anmeldungsdatum: 12.09.2006 Beiträge: 56
|
Verfasst am: 30.10.2006, 03:53 Titel: |
|
|
ebrady hat Folgendes geschrieben: | Jetzt bin ich wirklich festgefahren. Alles haut soweit hin, die dlls werden eingebunden. Aber irgendwie werden sie nicht richtig ausgeführt. Ehrlich gesagt hab ich aber wenig Hoffnung, dass mir jemand helfen kann.
|
Wie auch immer.
Aber ein paar mehr Infos wären schon hilfreich:
1. Wie sehen die DLLs überhaupt aus, wenn du hunderte davon hast, kannst du ja mal von einer den Quellcode posten.
2. Poste ein vollständiges zusammenhängendes Beispielprogramm, dazu gehört: Der Code der die FUNCTION ModulLaden(nummer,typ) as string aufruft, der Code mit dem die DLL Funktionen aufgerufen wird und am Schluß der Aufruf von FUNCTION ModulAbwerfen(nummer,typ) as string, alles an einem Stück.
3. Gibt es irgend einen Grund warum du noch nicht auf FB-v0_17b-jul-30-testing-win32 abgedated hast?
Als Tip oder besser gesagt als Forderung:
Deklariere auf jeden Fall alle Funktionsparameter nach Typ und Übergabekonvention also z.B.
FUNCTION ModulLaden(byval nummer as integer,byval typ as integer) as string, (natürlich nur wenn es auch byval und integer sein soll).
Zitat: |
Code: | print modul(zelle(i,3),1) |
gibt einen Wert um 85 Millionen zurück, obwohl eigentlich nur 1 oder 0 kommen sollte.
|
Das sieht schon mal ziemlich schräg aus, bei den 85 Millionen handelt es sich nur um die Funktionsadresse und nicht um das Ergebnis aus dem Aufruf der DLL, (das Array modul() enthält ja nicht die Funktionen der DLL selbst, sondern nur die Funktionsadressen und wenn man ein Print davor setzt, werden diese eben angezeigt), irgendwie mußt der Compiler auch wissen, dass er jetzt nicht die Funktionsadresse ausgeben soll, sondern die Funktion aufrufen muß, auf die diese Adresse zeigt, da fehlt mit Sicherheit ein Klammerpaar
Das müßte dann schon eher so auschauen:
Code: | print modul(zelle(i,3),1)() |
Der Inhalt der ersten Klammer bestimmt die Funktion die aufgerufen werden soll, der Inhalt der zweiten Klammer enthält, falls benötigt, die Funktionsparameter oder bleibt leer.
Nochn Tip verwende besser keine Funktions und Variablennamen, die unter Umständen auch Schlüsselwörter sein können, das führt nur zu Missverständnissen: Also besser kein handle sondern lieber my_func_handle oder MyFuncHandle oder so was.
Zitat: |
x und Funktion sind natürlich beide Integer
|
Das behaupten viele von sich. |
|
Nach oben |
|
 |
ytwinky

Anmeldungsdatum: 28.05.2005 Beiträge: 2624 Wohnort: Machteburch
|
Verfasst am: 30.10.2006, 09:55 Titel: |
|
|
terminate hat Folgendes geschrieben: | Gibt es irgend einen Grund warum du noch nicht auf FB-v0_17b-jul-30-testing-win32 abgedated hast? | ???
Ist das eine Aktualisierung oder Abwertung
(..ich weiß natürlich, daß 0.17b schon relativ 'stable' läuft..)
Gruß
ytwinky _________________
v1ctor hat Folgendes geschrieben: | Yeah, i like INPUT$(n) as much as PRINT USING.. | ..also ungefähr so, wie ich GOTO.. |
|
Nach oben |
|
 |
terminate
Anmeldungsdatum: 12.09.2006 Beiträge: 56
|
Verfasst am: 30.10.2006, 12:03 Titel: |
|
|
ytwinky hat Folgendes geschrieben: |
Ist das eine Aktualisierung oder Abwertung
(..ich weiß natürlich, daß 0.17b schon relativ 'stable' läuft..)
Gruß
ytwinky |
'abgedated' das ist der endgültige Verfall der Sprachkultur sowohl der englischen als auch der deutschen, muß wohl an der Uhrzeit gelegen haben .
Das war eigentlich mehr so ne allgemeine Frage, ich sehe 0.17b als Bugfix für 0.16b und würde es deshalb empfehlen, weniger wegen der neuen Funktionen, wenns darum gehen sollte kommt eigentlich nur FreeBASIC CVS in Frage, aber die CVS Versionen verwirren 0.16b Nutzer im ersten Moment mehr, als dass sie helfen, (Byref->Byval, option explicit, ..., etc.). |
|
Nach oben |
|
 |
ytwinky

Anmeldungsdatum: 28.05.2005 Beiträge: 2624 Wohnort: Machteburch
|
Verfasst am: 30.10.2006, 12:04 Titel: |
|
|
hihihi  _________________
v1ctor hat Folgendes geschrieben: | Yeah, i like INPUT$(n) as much as PRINT USING.. | ..also ungefähr so, wie ich GOTO.. |
|
Nach oben |
|
 |
ebrady
Anmeldungsdatum: 06.07.2005 Beiträge: 45
|
Verfasst am: 30.10.2006, 13:17 Titel: |
|
|
Zitat: | 3. Gibt es irgend einen Grund warum du noch nicht auf FB-v0_17b-jul-30-testing-win32 abgedated hast? |
Ja, gibt es. Ich hatte keine Ahnung, dass das existiert, aber werd's mir mal anschauen.
Zitat: |
Das sieht schon mal ziemlich schräg aus, bei den 85 Millionen handelt es sich nur um die Funktionsadresse und nicht um das Ergebnis aus dem Aufruf der DLL, (das Array modul() enthält ja nicht die Funktionen der DLL selbst, sondern nur die Funktionsadressen und wenn man ein Print davor setzt, werden diese eben angezeigt), irgendwie mußt der Compiler auch wissen, dass er jetzt nicht die Funktionsadresse ausgeben soll, sondern die Funktion aufrufen muß, auf die diese Adresse zeigt, da fehlt mit Sicherheit ein Klammerpaar
|
Alter Schwede, daran hab ich Dussel nun gar nicht gedacht!
Zitat: |
Das müßte dann schon eher so auschauen:
Code: | print modul(zelle(i,3),1)() |
Der Inhalt der ersten Klammer bestimmt die Funktion die aufgerufen werden soll, der Inhalt der zweiten Klammer enthält, falls benötigt, die Funktionsparameter oder bleibt leer. |
Genau das isses!
Zitat: |
Das behaupten viele von sich. |
OK, danke, du hast was gut bei mir *g* |
|
Nach oben |
|
 |
ebrady
Anmeldungsdatum: 06.07.2005 Beiträge: 45
|
Verfasst am: 30.10.2006, 15:24 Titel: |
|
|
Das mit dem dynamischen Linken entwickelt sich langsam zur Farce.
Mein jetziges Problem: Ich hätte eigentlich gerne globale Variablen, die sowohl im Hauptprogramm als auch in den DLLs gelten.
Normalerweise, dachte ich mir, müsste es doch so gehen:
Im Hauptprogramm:
Code: | COMMON SHARED i as integer |
Und in der DLL:
Code: | EXTERN IMPORT i alias "i" as integer
DIM SHARED i as integer |
Tut es aber nicht! Der Pointer auf die Variable wird scheinbar nicht übergeben, sondern i als lokal behandelt! Wenn man das DIM SHARED i as integer weglässt, kommt "undefined reference".
Ist sowas überhaupt möglich bei dynamischem Linken? |
|
Nach oben |
|
 |
terminate
Anmeldungsdatum: 12.09.2006 Beiträge: 56
|
Verfasst am: 30.10.2006, 18:36 Titel: |
|
|
Ich bin kein Fan von SHARED und COMMON SHARED hab ich noch gar nie benutzt, Variablen die ich an mehreren Orten gleichzeitig benötige, reiche ich im Normalfall Byref über alle Instanzen und Funktionen 'durch'. Ein bis zwei zusätzliche Variablen als Funktionsparameter sind normalerweise kein Problem und die Sache bleibt übersichtlich. Wenn ich eine ganze Liste von gleichartigen Variablen benötige verwende ich ein Array und übergebe dieses Byref als zusätzlichen Funktionsparameter. Bei unterschiedlichen Variablen verwende ich eigentlich nur noch TYPEs, (User Defined Types), und übergebe sie auch Byref oder als Adresse. Types als Funktionsparameter sind sehr flexibel, man erstellt einfach einen Type der alle möglichen Variablen enthält, egal wie groß egal wieviel, es wird immer nur eine einzige Referenz oder eine Adresse an die Funktion übergeben, innerhalb der Funktion pickt man sich dann aus dem Type einfach nur diejenigen Variablen heraus, die man wirklich benötigt.
Andere Möglichkeiten wären auch noch die Verwendung von globalen Funktionen, die statische Variablen enthalten und natürlich auch alle Arten von Pointerspielereien.
Das habe ich auch noch nie verwendet, glaube aber, dass das nur in Modulen funktioniert und nicht in DLLs egal ob statisch oder dynamisch.
Code: | EXTERN IMPORT i alias "i" as integer
|
|
|
Nach oben |
|
 |
ebrady
Anmeldungsdatum: 06.07.2005 Beiträge: 45
|
Verfasst am: 30.10.2006, 19:36 Titel: |
|
|
OK, werd ich mich...ähh die Variablen dann wohl doch übergeben müssen.
Ist vielleicht auch wirklich die bessere Lösung. |
|
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.
|
|