String von D richtig an PB DLL schicken [gelöst]

Anfängerfragen zum Programmieren mit PureBasic.
Benutzeravatar
gekkonier
Beiträge: 314
Registriert: 20.04.2007 09:06
Wohnort: Wien

String von D richtig an PB DLL schicken [gelöst]

Beitrag von gekkonier »

Hallihallo!

Ich habe folgendes Anliegen:

Ich würde gerne eine DLL für die Programmiersprache D basteln, und zwar in Purebasic. Die soll ned viel machen, eigentlich nur ein vorhandes JPEG resizen und dann abspeichern.
Den Pfad vom JPEG will ich mit einem String übergeben, woraus dann in PB so etwas in der Art wird (reduziertes Beispiel - ich mach da schon andere Dinge, aber so ähnlich sieht die ProcedureDLL halt aus):

Code: Alles auswählen

ProcedureDLL dll2(var.s)
   MessageRequester("hallo", var, 0)
EndProcedure
Damit ich einen wohlgeformten PB String übergeben kann brauch ich jetzt nur noch eine Information: Sind die Purebasic Strings so terminiert wie in C, oder gelten hier andere Konventionen?

Falls die Frage ein Quatsch ist steinigt mich bitte nicht, ich bin nur neugierig wie das alles Funktioniert und lerne durch ausprobieren ;)
Zuletzt geändert von gekkonier am 03.02.2009 16:01, insgesamt 2-mal geändert.
Benutzeravatar
R4z0r1989
Beiträge: 521
Registriert: 12.06.2005 18:06
Kontaktdaten:

Beitrag von R4z0r1989 »

hey gekkonier,

wenn ich mich nicht täusch muss man bei einer dll von purebasic das ganze im memory machen.

da ich aber nu keine zeit hab kann ich dir wenn nicht andre schneller sind später ein beispiel posten ;-)
Benutzeravatar
gekkonier
Beiträge: 314
Registriert: 20.04.2007 09:06
Wohnort: Wien

Beitrag von gekkonier »

Ich habe jetzt im Forum gefunden, dass purebasic einen Pointer auf einen nullterminierten String verlangt.

Ich würde das jetzt so in der DLL dann machen:

Code: Alles auswählen

ProcedureDLL dll2(*ptr)
   MessageRequester("pb MessageRequester", PeekS(*ptr))
EndProcedure
Wäre das eine richtige Vorgehensweise, oder ist das falsch?
Benutzeravatar
R4z0r1989
Beiträge: 521
Registriert: 12.06.2005 18:06
Kontaktdaten:

Beitrag von R4z0r1989 »

ja genau so denk ich dass es funktionier ;-)

wenn nicht kann ich dir leider auch nicht mehr helfen ^^
Benutzeravatar
cxAlex
Beiträge: 2111
Registriert: 26.06.2008 10:42

Beitrag von cxAlex »

gekkonier hat geschrieben:Ich habe jetzt im Forum gefunden, dass purebasic einen Pointer auf einen nullterminierten String verlangt.

Ich würde das jetzt so in der DLL dann machen:

Code: Alles auswählen

ProcedureDLL dll2(*ptr)
   MessageRequester("pb MessageRequester", PeekS(*ptr))
EndProcedure
Wäre das eine richtige Vorgehensweise, oder ist das falsch?
Das hier reicht vollkommen aus:

Code: Alles auswählen

ProcedureDLL dll2(Str.s)
  MessageRequester("pb MessageRequester", Str)
EndProcedure

CallFunctionFast(@dll2(), @"TestString")
Ich übergebe in PX auch Pointer auf Strings an PB Dlls, und PB kann das ganz einfach nativ.
Projekte: IO.pbi, vcpu
Pausierte Projekte: Easy Network Manager, µC Emulator
Aufgegebene Projekte: ECluster

Bild

PB 5.1 x64/x86; OS: Win7 x64/Ubuntu 10.x x86
DarkDragon
Beiträge: 6291
Registriert: 29.08.2004 08:37
Computerausstattung: Hoffentlich bald keine mehr
Kontaktdaten:

Beitrag von DarkDragon »

PB terminiert die Strings mit Zero. Desshalb verwendest du in D einfach toStringz(deinstring) (Z steht üblicherweise für Zero) zum konvertieren :wink: .

Code: Alles auswählen

ProcedureDLL dll2(Str.s)
  MessageRequester("pb MessageRequester", Str)
EndProcedure 
Muss also so aufgerufen werden:

Code: Alles auswählen

dll2(toStringz("Hallo, Welt!"));
Nun kommt es noch drauf an ob du Tango oder Phobos nutzt und welche Version. Bei einer alten Tango version hieß toStringz anders.
Angenommen es gäbe einen Algorithmus mit imaginärer Laufzeit O(i * n), dann gilt O((i * n)^2) = O(-1 * n^2) d.h. wenn man diesen Algorithmus verschachtelt ist er fertig, bevor er angefangen hat.
Benutzeravatar
gekkonier
Beiträge: 314
Registriert: 20.04.2007 09:06
Wohnort: Wien

Beitrag von gekkonier »

Ah, danke für die Erläuterungen!

Ich habs jetzt so geplant:

PB Dll:

Code: Alles auswählen

ProcedureDLL dll2(*ptr)
   MessageRequester("pb MessageRequester", PeekS(*ptr))
EndProcedure
D Programm, welches die DLL verwendet:

Code: Alles auswählen

import tango.stdc.stringz;
extern (C) void dll2(char* str);

void main() {
	dll2(toStringz("Hallo von D"));
}
Funktioniert prächtig.
Ein Problem hab ich nur noch:

Wenn ich das D Programm dann aufrufe erscheint wie gewüncht der Requester mit dem übergebenen "Hallo von D".
Aber nach Beendigung des Programmes kommt noch ein object.Exception: Access Violation, welches sicher von der D Seite daherkommt.
Das lustige daran ist aber, wenn ich dll2(toStringz("Hallo von D")); 2x aufrufe kommt diese Fehlermeldung nicht mehr.

Vermutlich mache ich da was auf der D Seite falsch - mit Pointern und so Kram bin ich sehr unbeholfen, und zumal ich so oder so relativ selten grössere Programme schreibe und deshalb alles schön simpel halten kann.

Falls man mit D eine PB Dll verwenden will muss man noch folgendes machen:

1. Compilieren der DLL in pb
2. die lib file die pb generiert NICHT verwenden
3. eine eigene lib file für d machen:
implib /s pbdll.lib pbdll.dll
4. D Programm wie oben
5. compilieren mit dmd main.d pbdll.lib

Wobei mit den Pointern auf Speicher usw, das hab ich in C schon nicht kapiert und verwende ich normalerweise auch nicht, deshalb könnte das falsch sein *g*

EDIT: Ich habe den Threadtitel jetzt angepasst, damit man besser weiss worum es eigentlich geht.
Benutzeravatar
milan1612
Beiträge: 810
Registriert: 15.04.2007 17:58

Beitrag von milan1612 »

Unicode-Ascii Kollision?
Bin nur noch sehr selten hier, bitte nur noch per PN kontaktieren
DarkDragon
Beiträge: 6291
Registriert: 29.08.2004 08:37
Computerausstattung: Hoffentlich bald keine mehr
Kontaktdaten:

Beitrag von DarkDragon »

Code: Alles auswählen

import tango.sys.SharedLib;
import tango.stdc.stringz;

typedef extern (C) void function(char* arg) tdll2;
tdll2 dll2;

void main() {
    auto library = SharedLib.load("Test.dll");
    if(library !is null) {
        dll2 = cast(tdll2) library.getSymbol("dll2");
        dll2(toStringz("Hallo von D"));

        library.unload();
    }
}
Ganz nach diesem Tutorial hier:
http://www.dsource.org/projects/tango/wiki/TutDLL

Funktioniert doch wunderbar ;-) .
Angenommen es gäbe einen Algorithmus mit imaginärer Laufzeit O(i * n), dann gilt O((i * n)^2) = O(-1 * n^2) d.h. wenn man diesen Algorithmus verschachtelt ist er fertig, bevor er angefangen hat.
Benutzeravatar
gekkonier
Beiträge: 314
Registriert: 20.04.2007 09:06
Wohnort: Wien

Beitrag von gekkonier »

Wohooooo, das funktioniert!
Danke danke danke!
:praise:
Antworten