DLL einbinden

Anfängerfragen zum Programmieren mit PureBasic.
puredll
Beiträge: 6
Registriert: 27.04.2010 09:26

DLL einbinden

Beitrag von puredll »

Ich purer Anfänger und benötige Unterstützung, wie ich eine DLL in ein PureBasic-Programm einbinde.
(Ich habe zwar schon im Forum gesucht, aber irgendwie waren die Beispiele für mich zu umfangreich.) :oops:

Damit es für mich erst einmal einfach bleibt, fange ich mit einen einfachen Beispiel an.


In Visual Basic sieht die Declaration einer einfachen Funktion wie folgt aus:

Code: Alles auswählen

DECLARE FUNCTION Add1 LIB "sammlung.dll" ALIAS "Add1" (BYVAL zahl AS LONG) AS LONG
In C# sieht es so aus:

Code: Alles auswählen

public class DLLTest
    {
        [DllImport("C:\\dlls\\sammlung.dll")]
        public static extern int Add1(int zahl);
    }
Wie mache ich das mit PureBasic?
Benutzeravatar
ts-soft
Beiträge: 22292
Registriert: 08.09.2004 00:57
Computerausstattung: Mainboard: MSI 970A-G43
CPU: AMD FX-6300 Six-Core Processor
GraKa: GeForce GTX 750 Ti, 2 GB
Memory: 16 GB DDR3-1600 - Dual Channel
Wohnort: Berlin

Re: DLL einbinden

Beitrag von ts-soft »

Code: Alles auswählen

Prototype.l Add1(zahl.l)

Define.i hDLL = OpenLibrary(#PB_Any, "sammlung.dll")
Global Add1.Add1

If hDLL
  Add1 = GetFunction(hDLL, "Add1")
EndIf

; beispiel
Debug Add1(100)
PureBasic 5.73 LTS | SpiderBasic 2.30 | Windows 10 Pro (x64) | Linux Mint 20.1 (x64)
Nutella hat nur sehr wenig Vitamine. Deswegen muss man davon relativ viel essen.
Bild
puredll
Beiträge: 6
Registriert: 27.04.2010 09:26

Re: DLL einbinden

Beitrag von puredll »

Danke! Hat alles bestens geklappt.

Jetzt habe ich noch eine Funktion, die einen String zurück gibt.
Theoretisch dachte ich, dass folgende Anbindung klappen müsste.
Ich bekomme den erwarteten String jedoch nicht zurück.

Code: Alles auswählen

Prototype.s GetMyString(address.l, length.l)

Define.i hDLL = OpenLibrary(#PB_Any, "sammlung.dll")
Global GetMyString.GetMyString
Global test.s

Dim daten.b(3)

daten(0) = 65
daten(1) = 66
daten(2) = 67

If hDLL
  GetMyString = GetFunction(hDLL, "GetMyString")
EndIf

; beispiel
test = GetMyString(@daten(0), 3)
Debug test
Benutzeravatar
hörmi
Beiträge: 106
Registriert: 10.07.2007 15:20
Kontaktdaten:

Re: DLL einbinden

Beitrag von hörmi »

Habs mal ausprobiert und auf die schnelle würde ich mal behaupten so könnte es funktionieren
aber ich bin mir sicher die anderen bringen später noch eine bessere lösung >:)

Code: Alles auswählen

Prototype.l GetMyString(address.l, length.l)

Define.i hDLL = OpenLibrary(#PB_Any, "sammlung.dll")
Global GetMyString.GetMyString
Global test.s

Dim daten.b(3)

daten(0) = 65
daten(1) = 66
daten(2) = 67

If hDLL
  GetMyString = GetFunction(hDLL, "GetMyString")
EndIf

; beispiel
test = PeekS(GetMyString(daten(0), 3))
Debug test
BildBild Bild
puredll
Beiträge: 6
Registriert: 27.04.2010 09:26

Re: DLL einbinden

Beitrag von puredll »

Nein, das klappt leider nicht. /:->
Kaeru Gaman
Beiträge: 17389
Registriert: 10.11.2004 03:22

Re: DLL einbinden

Beitrag von Kaeru Gaman »

Allocier doch einfach mal Speicher, anstatt ein ByteArray zu erstellen...
Der Narr denkt er sei ein weiser Mann.
Der Weise weiß, dass er ein Narr ist.
Benutzeravatar
ts-soft
Beiträge: 22292
Registriert: 08.09.2004 00:57
Computerausstattung: Mainboard: MSI 970A-G43
CPU: AMD FX-6300 Six-Core Processor
GraKa: GeForce GTX 750 Ti, 2 GB
Memory: 16 GB DDR3-1600 - Dual Channel
Wohnort: Berlin

Re: DLL einbinden

Beitrag von ts-soft »

Code: Alles auswählen

 Prototype.s GetMyString(address.i, length.l)

Define.i hDLL = OpenLibrary(#PB_Any, "sammlung.dll")
Global GetMyString.GetMyString
Global test.s = Space(#UNLEN)

If hDLL
  GetMyString = GetFunction(hDLL, "GetMyString")
EndIf

; beispiel
GetMyString(@test, #UNLEN)
Debug test 
PureBasic 5.73 LTS | SpiderBasic 2.30 | Windows 10 Pro (x64) | Linux Mint 20.1 (x64)
Nutella hat nur sehr wenig Vitamine. Deswegen muss man davon relativ viel essen.
Bild
puredll
Beiträge: 6
Registriert: 27.04.2010 09:26

Re: DLL einbinden

Beitrag von puredll »

Das letzte Beispiel geht auch nicht. Was bedeutet eigentlich "#UNLEN"? :oops:

-

Aber damit wir uns nicht verzetteln, sage ich was die Funktion "GetMyString" macht.

Ich übergebe eine Adresse auf ein Byte-Feld (oder eines beliebig allocierten Speichers)
und die Länge des genutzten Byte-Feldes. Je nach dem was in dem Byte-Feld steht,
kommt eine Meldung (String) zurück. Im Beispiel hatte ich das Byte-Feld mit 65, 66, 67 gefüllt.
Es können aber tatsächlich beliebige Werte zwischen 0 und 255 enthalten sein.

Ich dachte erst, dass die Lösung mit "PeekS" von hörmi passen könnte. Tut es aber nicht.

-

Mit C# kann ich die Funktion einwandfrei nutzen. Der C# Quelltext sieht wie folgt aus:

Code: Alles auswählen

using System;
using System.Collections.Generic;
using System.Text;
using System.Runtime.InteropServices;

namespace sammlung
{
    class Program
    {
        static void Main(string[] args)
        {
            byte[] werte = new byte[100];
            werte[0] = 33;
            werte[1] = 99;
            werte[2] = 255;
            string s = DLLTest.GetMyString(werte, 3);
            Console.WriteLine(s);
        }
    }

    public class DLLTest
    {
        [DllImport("sammlung.dll")]
        public static extern string GetMyString(byte[] werte, int length);
    }
}
Benutzeravatar
ts-soft
Beiträge: 22292
Registriert: 08.09.2004 00:57
Computerausstattung: Mainboard: MSI 970A-G43
CPU: AMD FX-6300 Six-Core Processor
GraKa: GeForce GTX 750 Ti, 2 GB
Memory: 16 GB DDR3-1600 - Dual Channel
Wohnort: Berlin

Re: DLL einbinden

Beitrag von ts-soft »

In dem C-Sharp Beispiel wird aber ein grösserer Speicher reserviert, als genutzt.
Also Dim daten.b(99) entspricht new byte[100];
Ansonsten sollte der Code von hörmi passen.
PureBasic 5.73 LTS | SpiderBasic 2.30 | Windows 10 Pro (x64) | Linux Mint 20.1 (x64)
Nutella hat nur sehr wenig Vitamine. Deswegen muss man davon relativ viel essen.
Bild
puredll
Beiträge: 6
Registriert: 27.04.2010 09:26

Re: DLL einbinden

Beitrag von puredll »

Das mit der Speicherreservierung stimmt schon. Jedoch ist dies in diesem Fall egal, da sowieso nur 3 Bytes genutzt wurden.

Aber ich habe den Fehler von hörmi gefunden!
Er hat ein @ vergessen... Hier mein komplettes PureBasic-Testprogramm:

Code: Alles auswählen

Prototype.l Add1(zahl.l)
Prototype.l GetMyString(werte.l, length.l)

Define.i hDLL

Global Add1.Add1
Global GetMyString.GetMyString

hDLL = OpenLibrary(#PB_Any, "sammlung.dll")
If hDLL
  Add1 = GetFunction(hDLL, "Add1")
  GetMyString = GetFunction(hDLL, "GetMyString")
EndIf

Global test.s
Global zahl.l
Global Dim daten.b(100)

daten(0) = 33
daten(1) = 99
daten(2) = 255

zahl = Add1(999)
Debug "Add1() = " + Str(zahl)

;test = PeekS(GetMyString(daten(0), 4))   <-- Hier der Fehler von hörmi
test = PeekS(GetMyString(@daten(0), 4))
Debug "GetMyString() = " + test
Vielen Dank! Ohne die Hilfe hier hätte ich ewig gegrübelt! :allright:
Antworten