Seite 1 von 2

DLL einbinden

Verfasst: 27.04.2010 16:56
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?

Re: DLL einbinden

Verfasst: 27.04.2010 17:11
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)

Re: DLL einbinden

Verfasst: 28.04.2010 10:04
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

Re: DLL einbinden

Verfasst: 28.04.2010 10:16
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

Re: DLL einbinden

Verfasst: 28.04.2010 11:02
von puredll
Nein, das klappt leider nicht. /:->

Re: DLL einbinden

Verfasst: 28.04.2010 11:41
von Kaeru Gaman
Allocier doch einfach mal Speicher, anstatt ein ByteArray zu erstellen...

Re: DLL einbinden

Verfasst: 28.04.2010 13:29
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 

Re: DLL einbinden

Verfasst: 28.04.2010 14:59
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);
    }
}

Re: DLL einbinden

Verfasst: 28.04.2010 15:10
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.

Re: DLL einbinden

Verfasst: 28.04.2010 15:27
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: