PureBasic DLL in anderem Projekt (andere Sprache) nutzen

Windowsspezifisches Forum , API ,..
Beiträge, die plattformübergreifend sind, gehören ins 'Allgemein'-Forum.
Jenseden
Beiträge: 6
Registriert: 23.08.2021 09:32

PureBasic DLL in anderem Projekt (andere Sprache) nutzen

Beitrag von Jenseden »

Hallo zusammen,

ich möchte Funktionen einer in PureBasic erstellte Win32-DLL von einer anderen Programmiersprache aus aufrufen.
Ist hier bzgl. der PureBasic-Datentypen etwas besonderes zu beachten, insbes. bei den Strings? Alle Versuche endeten bisher im direkten Absturz beim Aufruf der Funktionen.

Danke im Voraus.
Axolotl
Beiträge: 146
Registriert: 31.12.2008 16:34

Re: PureBasic DLL in anderem Projekt (andere Sprache) nutzen

Beitrag von Axolotl »

Hallo Jenseden,
ich denke es gibt dabei einiges zu beachten. Allerdings is DLL nicht mein Spezialgebiet.
Vielleicht steht in der Hilfe unter Building a DLL noch etwas.
Insbesondere dieser Hinweis:
Note about returning strings from DLL's:

If you want to return a string out of a DLL, the string has to be declared as Global before using it.


Klappt denn der Zugriff mit PureBasic-Executable auf die DLL?
Mostly running PureBasic <latest stable version and current alpha/beta> (x64) on Windows 11 Home
Jenseden
Beiträge: 6
Registriert: 23.08.2021 09:32

Re: PureBasic DLL in anderem Projekt (andere Sprache) nutzen

Beitrag von Jenseden »

Hallo,

ich selber habe kein PureBasic im Einsatz, sondern versuche eine in PureBasic erstellte Win32-DLL in meinem Projekt zu verwenden. Das was ich hier im Forum gefunden habe, beschreibt leider größtenteils die andere Richtung. Der Ersteller der DLL bietet Wrapper-Code für VB an, um die Funktionen seiner DLL in VB/VBA nutzen zu können, aber das hilft mir bisher nicht weiter.
Benutzeravatar
chi
Beiträge: 90
Registriert: 17.05.2007 09:30
Wohnort: Linz - Austria

Re: PureBasic DLL in anderem Projekt (andere Sprache) nutzen

Beitrag von chi »

Hi, wenn du uns verrätst um welche DLL es sich handelt, könnten wir wahrscheinlich besser helfen ;). Welche Sprache verwendest du in deinem Projekt? Ist die DLL x86 oder x64 und verwendest du die selbe Architektur für dein Projekt?
Jenseden
Beiträge: 6
Registriert: 23.08.2021 09:32

Re: PureBasic DLL in anderem Projekt (andere Sprache) nutzen

Beitrag von Jenseden »

Hallo,
es handelt sich um eine PureBasic 32 bit DLL, ich verwende in meinem Projekt die selbe Architektur. Mein Projekt ist in der ziemlich unbekannten "Clarion" Sprache entwickelt, ich kenne mich aber in der Verwendung von Win32-DLLs gut aus (z.B. binde ich Combit List&Label ebenso an oder verwende Windows API-Funktionen ohne Probleme). Die Übersetzung der Funktionsdeklarationen nach Clarion ist i.d.R. keine große Kunst.

Der Hersteller der DLL hat mir die Auskunft gegeben, dass er diese DLL in PureBasic erstellt hat und ausschließlich VB6/VBA unterstützt. (Es handelt sich im übrigen um ein Update, die vorherige Version der DLL war wohl in VB erstellt und diese habe ich problemlos einbinden können.) Die Aussage, dass ausschließlich VB6/VBA von der PureBasic DLL unterstützt wird finde ich eigenartig, da PureBasic DLLs nach dem was ich hier im Forum gefunden habe, übliche Win32-Dlls sein sollten.

Es stürzt allerdings bereits der Aufruf der init-Funktion ab (erwartet einen String und gibt einen Long zurück). Im VB-Wrapper Code des Herstellers ist diese Funktion wie folgt deklariert:
Private Declare Function Init Lib "xxx.DLL" (InitStr As String) As Long
-> InitStr müsste demnach ein CSTRING (nullzeichenterminiert) sein und der Rückgabewert ein 32 Bit Ganzzahlwert.
Axolotl
Beiträge: 146
Registriert: 31.12.2008 16:34

Re: PureBasic DLL in anderem Projekt (andere Sprache) nutzen

Beitrag von Axolotl »

Hallo,
ich glaube, dass wir hier ein bisschen im Nebel stochern. Da Du die DLL nicht benennst, ist es wohl keine allgemein verfügbare?
Die Aussage, dass ausschließlich VB6/VBA von der PureBasic DLL unterstützt wird finde ich eigenartig, da PureBasic DLLs nach dem was ich hier im Forum gefunden habe, übliche Win32-Dlls sein sollten.
Nun ja, hier würde ich sagen, dass es mehrere Aspekte gibt:
Technisch: Hast du wahrscheinlich Recht.
Leistungsangebot (in Richtung Lizenz und Gewährleistung): Wenn der Ersteller hier Einschränkungen macht, dann darf er das ja .... Wenn er es nur gegen VB getestet hat möchte er vielleicht auch nicht jede beliebige Sprache unterstützen, wenn es Probleme gibt.

Aber das ist ein anderes Thema, ich stocher mal weiter:
Absturz aufgrund von unerlaubten Speicherzugriff....
Neben unterschieden durch 32/64 bit Apps gibt es noch ANSI, UTF8, UNICODE, etc. bei strings. (Ich kenne jetzt 'Clarion' überhaupt nicht.)
Mostly running PureBasic <latest stable version and current alpha/beta> (x64) on Windows 11 Home
Jenseden
Beiträge: 6
Registriert: 23.08.2021 09:32

Re: PureBasic DLL in anderem Projekt (andere Sprache) nutzen

Beitrag von Jenseden »

Axolotl hat geschrieben: 23.08.2021 15:44 ich glaube, dass wir hier ein bisschen im Nebel stochern. Da Du die DLL nicht benennst, ist es wohl keine allgemein verfügbare?
Korrekt, ist ein gekauftes 3rdParty Produkt
Leistungsangebot (in Richtung Lizenz und Gewährleistung): Wenn der Ersteller hier Einschränkungen macht, dann darf er das ja .... Wenn er es nur gegen VB getestet hat möchte er vielleicht auch nicht jede beliebige Sprache unterstützen, wenn es Probleme gibt.
richtig, das kann er natürlich so machen. Ich wollte mich jetzt nur bzgl. der prinzipiellen technische Möglichkeit vergewissern.
Neben unterschieden durch 32/64 bit Apps gibt es noch ANSI, UTF8, UNICODE, etc. bei strings.
bzgl. Encoding werde ich nochmal testen, danke für die Idee.
H.Brill
Beiträge: 356
Registriert: 15.10.2004 17:42
Wohnort: 66557 Neunkirchen

Re: PureBasic DLL in anderem Projekt (andere Sprache) nutzen

Beitrag von H.Brill »

Wie werden denn in Clarion die Strings an eine DLL übergeben ?
Ich meine damit, ob per Value oder per Reference. Per Value
wird da nicht funktionieren, da PB eine Adresse auf einen
String bzw. Speicherbereich erwartet.
Und, wie oben schon gesagt, daß das Nullbyte am Ende ist.
Damals hatte man z.B. viel Ärger mit normalen Pascal-Strings,
da diese die Stringlänge am Stringanfang speicherten.

In deiner VB-Deklaration ist das nicht ersichtlich. Ich weiß
jetzt auch nicht, wie VB standardmäßig solche Strings übergibt.

Nach meiner Erfahrung kann das auch Probleme bereiten.
Hatte ich auch schon mal. Oder probiere mal, einen String
in einen normalen Speicherbereich (allocate) zu schieben
und diesen übergeben.
PB 5.60
Benubi
Beiträge: 186
Registriert: 22.10.2004 17:51
Wohnort: Berlin, Wedding

Re: PureBasic DLL in anderem Projekt (andere Sprache) nutzen

Beitrag von Benubi »

Seit einigen neueren PB Versionen werden alle Strings intern im Unicode Format verarbeitet, daher ist das auch der Standard bei Rückgaben von Strings.Auf der DLL Seite empfiehlt es sich die Strings zu PeekS'en. Das Format kannst Du dir aussuchen, möglicherweise richtest Du Dich an die Clarion Programmiersprache, was die intern benutzt. Wenn die Unicode benutzt, so wie PB, würde ich auch die Strings als Unicode übergeben weil dann der String einfach kopiert wird ohne konvertiert werden zu müssen.

Code: Alles auswählen

ProcedureDLL myProc(*Param1Str, Param2.d) ; String und Double
   Protected Str1$ 
   Str1$=PeekS(*Param1Str, -1, #PB_Unicode) ; Unicode String
  ProcedureReturn #Null
EndProcedure
Bei der Rückgabe von Strings an das Aufrufende Hauptprogramm hat es manchmal Probleme gegeben (weiß nicht ob noch so ist). Wenn Clarion Unicode as Rückgabe erwartet, aber deine Strings nicht erkannt werden und Datenmüll erscheint, mußt Du es mit einer Globalen Variable als Rückgabe probieren:

Code: Alles auswählen

Global myProc2_ergebnis$ ; 
ProcedureDLL myProc2()
 Protected irgendwas$ 
  myProc2_ergebnis$ = "Ergebnis 12345"
   ProcedureReturn myProc2_ergebnis$
EndProcedure
Ich habe jetzt lange nicht mehr sowas probiert. Vielleicht geht es auch ohne "Global" entzwischen (möglicherweise geht das auch mit "shared" Variablen aber ich habe das nicht probiert).
Jenseden
Beiträge: 6
Registriert: 23.08.2021 09:32

Re: PureBasic DLL in anderem Projekt (andere Sprache) nutzen

Beitrag von Jenseden »

hallo zusammen,

Danke zunächst für die Beiträge. Das Übergeben von nullterminierten Strings anhand der Adresse an die DLL klappt. (Es handelt sich um einfache ANSII 8-bit Strings.)
Problem ist nun noch die Rückgabe von Stringwerten. Der Ersteller der DLL hat hierfür den Datentyp "Variant" verwendet, by Reference.
Ich nehme mal an, das dieser Datentyp mit den VB-Variants kompatibel ist.

Ein Funktionsdeklaration in der PureBasic DLL sieht z.B. so aus:

Code: Alles auswählen

ProcedureDLL.l SomeFunction(*X.integer, *Y.integer, *Z.variant)
wobei X und Y String-Pointer sind und Z wohl ein Variant-Pointer, Funktionswert ist ein 32 bit Long.

Der Ersteller der DLL stellt VB6-Wrapper Code für den Aufruf der DLL-Funktionen zur Verfügung. Der sieht für den Aufruf dieser Funktion wie folgt aus:

Code: Alles auswählen

Public Function vbSomeFunction(ByVal X As String, ByVal Y As String, ByRef Z As String) As Long
  Dim Result As Long
  Dim vZ As Variant
  
  Z = ""
  
  Result = SomeFunction(X, Y, vZ)
  If Result = 0 Then
    Z = CStr(vZ)
  End If
  
  vbSomeFunction= Result
End Function
Clarion unterstützt native keine Variants, so dass ich den Zugriff auf den zurückgegebenen Stringwert selber von Hand programmieren muss. Den Aufbau eines Variants habe ich ergoogelt. Ich habe dabei folgendes Problem. Die Adresse des Variants ändert sich beim Aufruf der Funktion. Wenn ich auf den Speicherbereich der neuen Adresse zugreife (memcpy), erhalte sich sofort einen Absturz. Somit komme ich an den zurückgegebenen Stringwert nicht heran.
Antworten