 |
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 |
aschaffenburger
Anmeldungsdatum: 06.11.2006 Beiträge: 3
|
Verfasst am: 06.11.2006, 07:45 Titel: Altes Thema FB und DLL für Visual-Basic |
|
|
Hallo alle zusammen!
Ich habe ein altbekanntes Problem. Also Oberfläche möchte ich Visual-Basic nutzen und die Rechenpower in einer FB-DLL unterbringen. Da ich ein Programm mit neuronalen Netzen schreibe ist der Geschwindigkeitsvortteil wohl nicht unerheblich
Irgendwie bringe ich es aber mit der Datenübergabe nicht auf die Reihe. Ich habe bestimmt schon über 12 Stunden damit verbracht und unzähliege Varianten ausprobiert. Entweder hängt sich Visual-Basic auf, es gibt dubiose Fehlermeldungen oder das Ergebiss ist einfach Sch....
In FB selbst jedoch läuft das neurnale Netzwerk fehlerfrei nur in der DLL nicht.
Hier ist auszugsweise mein Code ohne Variablendeklaration usw:
================================================================
Auf FB-Seite:
Function Prognose Alias "PROGNOSE" ( Eingabe1() As Double, ErgebnissArray1() _
As Double)as double Export
.
.
Prognose=1
End Function
Auf VB-Seite:
Public Declare Function Prognose Lib "NNeigen2dll.dll" Alias "PROGNOSE@8" _
(ByRef Eingabe() As Double, ErgebnissArray() As Double) As Double
EingabeArray(0) = 0.1
Eingabe(Array1) = 0.3
Prognose EingabeArray(), ErgebnissArray()
A= ErgebnissArray(0)
================================================================
Bei dieser Variante meines Codes bekomme ich die Fehlermeldung das ein Schreibbehl auf Stpeicherstelle xxxx fehlgeschlagen ist.
Kann mir irgendjemand helfen? Ich zweifele langsam an meinem Verstand!!
Bei Interesse veröffentliche ich gerne den kompletten Code mit einer Beschreibung dazu. |
|
Nach oben |
|
 |
ebrady
Anmeldungsdatum: 06.07.2005 Beiträge: 45
|
Verfasst am: 06.11.2006, 09:32 Titel: |
|
|
Mal versucht, die DLL unter FreeBasic einzubinden und zu testen ob sie einwandfrei läuft? Sind die verwendeten Variablentypen EXAKT dieselben?
Vielleicht auch mal versuchen, CDECL als Übergabekonvention zu verwenden. (siehe Stichwort EXPORT in FBRef) |
|
Nach oben |
|
 |
croco97

Anmeldungsdatum: 04.11.2005 Beiträge: 260
|
Verfasst am: 06.11.2006, 14:49 Titel: |
|
|
Ich würde auf alle Fälle mal im Argument der Funktionendeklaration "ByRef" vor die Arrays stellen. Das muss sichergestellt sein, sonst sind die Arrays im Hauptprogramm nicht initialisiert.
Zweitens klappt das ev. immer noch nicht, da die ()-Arrays FB/QB-spezifische Speicherobjekte sind. Aus FB heraus gibt's hier die Möglichkeit, die C-like-Arrays mittels allocate und [] zu benutzen. Wenn das VB auch kann, dann ist diese Austauschmethode aussichtsreicher. Wenn alles nichts hilft: Einfach das Array in einen zstring übertragen. Den können VB und FB mit Sicherheit austauschen.
Zum Thema Libs, zstrings etc. kannst du im Oma-Tutorial, Teil 3, was nachlesen.
Viele Grüsse!
Croco |
|
Nach oben |
|
 |
terminate
Anmeldungsdatum: 12.09.2006 Beiträge: 56
|
Verfasst am: 06.11.2006, 17:57 Titel: Re: Altes Thema FB und DLL für Visual-Basic |
|
|
aschaffenburger hat Folgendes geschrieben: | ... Ich habe ein altbekanntes Problem. Also Oberfläche möchte ich Visual-Basic nutzen und die Rechenpower in einer FB-DLL unterbringen... |
Ein durchaus pragmatischer Ansatz, hab ich ich früher auch schon gemacht mit VB6 und selbstgeschriebenen 'Mini' C DLLs.
Es ist allerding schon ziemlich mutig, davon auszugehen, dass VB das gleiche Variablen oder gar Arrayformat benutzt wie Freebasic.
Machs uns ein bisschen einfacher und poste zwei komplette, (zumindest im Prinzip kompilier und lauffähige), Kurzbeispiele von der VB und der Freebasicseite, (die müssen erst mal auch gar nichts mit deinem eigentlichen Programm zu tun haben), wir wollen jetzt einfach mal herausfinden, was man so alles zwischen VB, (Version6 oder .net ?), hin und herreichen kann, ich tippe mal darauf, dass ohne Nacharbeit nur Integer, Long und Zstring funktionieren. |
|
Nach oben |
|
 |
Mao
Anmeldungsdatum: 25.09.2005 Beiträge: 4409 Wohnort: /dev/hda1
|
Verfasst am: 06.11.2006, 18:27 Titel: |
|
|
Zumindest bei Delphi so, dass man ANSI-Strings und Array's (bzw. Datenstrukturen) nur mit einer speziellen Sharing-DLL mit anderen Programmen teilen kann. Heißt, zusätzlich zu deiner eigenen DLL brauchst du bei Delphi auch noch die Borland Memory Managing-DLL. Evtl. hat FB einen ähnlichen Ansatz? _________________ Eine handvoll Glück reicht nie für zwei.
--
 |
|
Nach oben |
|
 |
aschaffenburger
Anmeldungsdatum: 06.11.2006 Beiträge: 3
|
Verfasst am: 06.11.2006, 19:22 Titel: |
|
|
Hallo,
vielen herzlichen dank für die prompte Hilfe
Alle Tips habe ich auch schon getestet - leider ohne Erfolg. Ich programmiere in VB6.
Nun bin ich soweit das ich wenigstens den Rückgabewert einer Funktion in der DLL bekomme. Es klappt aber einfach noch nicht ein komplettes Array an VB zurück zu geben
Als datentyp verwende ich hier auschließlich Double da er in beiden Sprachen klar mit der gleichen Größe und Wertebereich definiert ist. Hat da jemand noch eine Idee?
Ich werde auf jeden Fall weiter experimentieren und euch auf dem laufenden halten.
Beste Grüße
aschaffenburger |
|
Nach oben |
|
 |
croco97

Anmeldungsdatum: 04.11.2005 Beiträge: 260
|
Verfasst am: 06.11.2006, 22:39 Titel: |
|
|
Wie ich schon oben geschrieben habe: Double allein sagt bei Arrays noch gar nichts. Also:
- ByRef ausprobiert?
- C-Arrays ausprobiert?
- Array in Zstring packen ausprobiert?
Letzteres klappt garantiert.
Viele Grüsse!
Croco |
|
Nach oben |
|
 |
terminate
Anmeldungsdatum: 12.09.2006 Beiträge: 56
|
Verfasst am: 07.11.2006, 01:05 Titel: |
|
|
Ich hab hier mal ein paar Beispiele zusammengestellt, funktioniert so, lässt sich aber sicher auch noch anders realisieren:
(Weiterführende Informationen:
http://www.microsoft.com/germany/msdn/library/windows/api/UndokumentierteVariablenzeiger.mspx?mfr=true
http://www.freebasic.net/forum/viewtopic.php?p=21823#21823
http://www.microsoft.com/germany/msdn/library/visualtools/vb6/AuslesenEinesStringsAusEinerCStrukturInVB.mspx?mfr=true)
In FreeBASIC:
mydll.bas
Code: |
#include "windows.bi"
Function add_nums Alias "add_nums" ( ByVal num_1 As Integer, ByVal num_2 As Integer) As Integer Export
return num_1 + num_2
End Function
Function square_calc alias "square_calc" ( ByVal num_1 As Double) As Double Export
return num_1^2
End Function
function show_string_method_1 alias "show_string_method_1" (byref mystring as string)as integer Export
MessageBox(0, mystring, "Freebasic Messagebox", MB_OK )
return 0
end function
function change_string alias "change_string" (byval my_string_ptr as any ptr)as integer Export
dim tmp_str as wstring * 10
tmp_str=wstr("bye")
CopyMemory(my_string_ptr, @tmp_str, len(tmp_str)*2)
return 0
end function
function show_double_array alias "show_double_array" (byval my_double_array_ptr as double ptr, byval array_len) as integer export
dim i as integer
dim my_double as double
dim tmp_str as string
for i = 0 to array_len
my_double=my_double_array_ptr[i]
tmp_str=tmp_str+str(my_double) & chr$(13)
next i
MessageBox(0, tmp_str, "Freebasic Messagebox", MB_OK )
return 0
end function
function change_double_array alias "change_double_array" (byval my_double_array_ptr as double ptr, byval array_len) as integer export
dim my_double as double
my_double =0.004567
my_double_array_ptr[0]=my_double
my_double =-0.00998
my_double_array_ptr[1]=my_double
my_double =23456.6667
my_double_array_ptr[2]=my_double
'...
my_double =1103
my_double_array_ptr[20]=my_double
return 0
end function
|
In VB6:
Form1.frm
Code: |
Private Sub Command1_Click()
Dim retval As Integer 'allgemeine Rueckgabevariable
Dim a, b, s, i As Integer
Dim c, r As Double
Dim my_str As String
Dim a_my_doubles(20) As Double
'**********************************
a = 12
b = 13
s = add_nums(a, b)
retval = MsgBox(s, vbOKOnly, "VB-Messagebox")
'**********************************
c = 3.14
r = square_calc(c)
retval = MsgBox(r, vbOKOnly, "VB-Messagebox")
'**********************************
my_str = "hello"
retval = show_string_method_1(my_str)
'**********************************
my_str = "hello"
retval = change_string(StrPtr(my_str))
retval = MsgBox(my_str, vbOKOnly, "VB-Messagebox")
'**********************************
a_my_doubles(0) = 23.5
a_my_doubles(1) = 3.41
a_my_doubles(2) = 42.7
a_my_doubles(3) = -0.3
'...
a_my_doubles(20) = -3056.659
retval = show_double_array(a_my_doubles(0), UBound(a_my_doubles))
'**********************************
retval = change_double_array(a_my_doubles(0), UBound(a_my_doubles))
my_str = ""
For i = 0 To UBound(a_my_doubles)
my_str = my_str & Str(a_my_doubles(i)) & Chr$(13)
Next i
retval = MsgBox(my_str, vbOKOnly, "VB-Messagebox")
End Sub
|
Module1.bas
Code: |
Public Declare Function add_nums Lib "MEIN_DLL_PFAD\mydll.dll" Alias "add_nums@8" (ByVal num_1 As Integer, ByVal num_2 As Integer) As Integer
Public Declare Function square_calc Lib "MEIN_DLL_PFAD\mydll.dll" Alias "square_calc@8" (ByVal num_1 As Double) As Double
Public Declare Function show_string_method_1 Lib "MEIN_DLL_PFAD\mydll.dll" Alias "show_string_method_1@4" (ByRef mystring As String) As Integer
Public Declare Function change_string Lib "MEIN_DLL_PFAD\mydll.dll" Alias "change_string@4" (ByVal my_string_ptr As Long) As Integer
Public Declare Function show_double_array Lib "MEIN_DLL_PFAD\mydll.dll" Alias "show_double_array@8" (ByRef my_double_array_ptr As Double, ByVal array_len As Integer) As Integer
Public Declare Function change_double_array Lib "MEIN_DLL_PFAD\mydll.dll" Alias "change_double_array@8" (ByRef my_double_array_ptr As Double, ByVal array_len As Integer) As Integer
|
|
|
Nach oben |
|
 |
Michael712 aka anfänger, programmierer
Anmeldungsdatum: 26.03.2005 Beiträge: 1593
|
Verfasst am: 07.11.2006, 16:15 Titel: |
|
|
Ähm, die Alias namen kommen mir komisch vor.
Soweit ich weiß, gibt das "@" an, an welcher Stelle in der dll die Funktion steht.
Normalerweise macht man das unter windows anders, man erstellt eine dll.def datei, in der das alles steht. Da gibts auch irgendwo ein Prog zu, welches bei FreeBASIC dabei ist. Dann musst du bei den Alias namen einfach das @x weglassen. _________________
Code: | #include "signatur.bi" |
|
|
Nach oben |
|
 |
terminate
Anmeldungsdatum: 12.09.2006 Beiträge: 56
|
Verfasst am: 07.11.2006, 19:18 Titel: |
|
|
programmierer hat Folgendes geschrieben: | Ähm, die Alias namen kommen mir komisch vor.
Soweit ich weiß, gibt das "@" an, an welcher Stelle in der dll die Funktion steht.
|
Das hat schon seine Richtigkeit so, der Name vor dem Alias gibt an wie die Funktion in Visualbasic heißen soll also z.B. add_nums, der Name nach dem Alias gibt an, wie die Funktion tatsächlich in der FreeBASIC DLL heißt und da heißt sie eben add_nums@8 und zwar genau so. Ich kann jetzt z.B. mit einem Hexeditor hergehen und den Funktionsnamen in der DLL in add_nums@9 ändern, dann muß ich halt in VB nacher Alias "add_nums@9 schreiben, funktioniert auch. Viele Compiler erlauben es auch das Name Mangling durch Compiler Switches 'auszulagern', dann kann man auf das Alias verzichten. In der Standardeinstellung produziert FreeBASIC aber immer DLLs, die den Funktionsnamen gefolgt von einem @ gefolgt von der Anzahl der Summe der Bytes der Funktionsparameter enthalten.
Manchmal kann man aber trotzdem nicht auf das Alias verzichten, da manche Compiler den Funktionsnamen, (vor dem Alias), immer in Upper oder Lowercase übersetzen, wenn der Funktionsname in der DLL dann eben gerade groß oder klein geschrieben ist hat man Pech gehabt.
EDIT:
@programmierer
Was du meinst sind die Ordinalzahlen der DLL Funktionen, stimmt die werden auch mit einem @ davor geschrieben, (angeblich ein Überbleibsel aus der 16Bit Zeit, wenn man diesem Link glauben darf:
http://www.openwatcom.org/index.php/Visual_Basic_Integration)
Trotzdem, das mit dem Alias und dem Funktionsname@Nummer ist schon lästig, bei dlltool.exe, das auch Freebasic verwendet um seine DLLs zu erzeugen, gibt es sogar einen Parameter, (-k), der das unterbindet, leider kenne ich keine Freebasic Compiler Option um diesen Parameter zu übergeben.
Zuletzt bearbeitet von terminate am 07.11.2006, 20:20, insgesamt einmal bearbeitet |
|
Nach oben |
|
 |
aschaffenburger
Anmeldungsdatum: 06.11.2006 Beiträge: 3
|
Verfasst am: 07.11.2006, 19:31 Titel: |
|
|
Hallo terminate,
vielen herzlichen Dank und ein superdickes Lob für das ABSOLUT ausführliche Beispiel
Die Sache mit dem Pointer war der springende Punkt (hatte es zwar auch probiert aber wohl etwas falsch gemacht )
Jetzt klappt alles bestens und die Rechenpower gegenüber VB ist um mindestens das 10-fache gestiegen
Ich wünsche Dir und allen anderen noch einen schönen Abend
Beste Grüße
aschaffenburger
PS: das obrige Angebot steht natürlich noch. Ich beschäftige mich seit einiger Zeit mit neuronalen netzwerken und deren Möglichkeiten. Bei Interesse veröffentliche ich gerne meinen Code mit einer kleinen Beschreibung zur Anwendung |
|
Nach oben |
|
 |
ebrady
Anmeldungsdatum: 06.07.2005 Beiträge: 45
|
Verfasst am: 07.11.2006, 20:05 Titel: |
|
|
Hi,
ich würde es mir auf jeden Fall mal angucken. Habe ein Projekt, bei dem sowas eine Überlegung wert wäre mit einzubauen, wenn dann aber wahrscheinlich erst in einer späteren Version.
Grüsse |
|
Nach oben |
|
 |
Mao
Anmeldungsdatum: 25.09.2005 Beiträge: 4409 Wohnort: /dev/hda1
|
Verfasst am: 07.11.2006, 20:44 Titel: |
|
|
Hallöschen!
Is' immer toll, wenn man sieht, was andere Programmierer so in ihrer Freizeit machen -> ab in das Projektvorstellungsforum damit.  _________________ Eine handvoll Glück reicht nie für zwei.
--
 |
|
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.
|
|