![]() |
Win32 DLL erstellen
Liste der Anhänge anzeigen (Anzahl: 1)
Hallo,
ist schon eine Weile her, dass ich mit Delphi mal was gemacht habe und im Moment komme ich bei folgendem Problem nicht weiter: Ich wuerde gerne ein Extension-DLL fuer einen virtuellen Drucker-Treiber mit Delphi ertellen - Win32 DLL mit Unicode Support - habe angefangen, das entsprechende C-Headerfile umzusetzen, aber irgdendwie scheint das ganze nicht zu funktionieren. Hier das C-Headerfile:
Delphi-Quellcode:
enum
{ SC_OUTPUT_BLACKWHITE = 1, SC_OUTPUT_GRAYSCALE, SC_OUTPUT_COLOR, }; enum { SC_TIFTYPE_NONE = 1, SC_TIFTYPE_PACKBITS, SC_TIFTYPE_CCITT_HUFFMAN, SC_TIFTYPE_CCITT_T4, SC_TIFTYPE_CCITT_T6, SC_TIFTYPE_JPEG, }; typedef struct _SCJOBINFO { // Form name TCHAR formName[32]; // Only values between 100 to 300 dpi are accepted int printQuality; // One of SC_OUTPUT_BLACKWHITE to SC_OUTPUT_COLOR int colorType; // Only values between 1 to 100 are accepted. // Higher value means better quality. int jpegQuality; // One of SC_TIFTYPE_NONE to SC_TIFTYPE_JPEG. // PackBits and one of the CCITT types are only applicable if colorType // is set to SC_OUTPUT_BLACKWHITE. int tiffCompression; // Only applicable if tiffCompression is set to SC_TIFTYPE_JPEG. // Only values between 1 to 100 are accepted. // Higher value means better quality. int tiffQuality; // Only values between 1 to 100 are accepted. // Higher value means better quality. int pdfQuality; } SCJOBINFO; enum { SC_BMP = 1, SC_PNG, SC_JPG, SC_TIF_SINGLE, SC_PDF_SINGLE, SC_TIF_MULTIPLE, SC_PDF_MULTIPLE, }; typedef struct _SCFILEINFO { // Output filename without extension. This parameter is required. wchar_t name[MAX_PATH]; // Extension of output filename. This parameter is optional. // If none is supplied, a default extension will be used. wchar_t ext[MAX_PATH]; // Output image type, which could be one of SC_BMP to SC_PDF_MULTIPLE. <tt>SC_PDF_MULTIPLE</tt>. // This parameter is required. int type; } SCFILEINFO; typedef BOOL (WINAPI *SCGETJOBINFOFUNC) (SCJOBINFO*); typedef BOOL (WINAPI *SCGETSAVEFILENAMEFUNC) (SCFILEINFO*); typedef void (WINAPI *SCENDOFJOBFUNC) (); Hier, was ich bislang gemacht habe:
Delphi-Quellcode:
Code kompiliert, aber ich bekomme bei der Benutzung des Treibers eine "Memory could not be read" Execptions - irgendeine Idee ? Ich gehe einmal davon aus, dass ich etwas grobes falsch mache, was Uebergabe-Parameter und dergleichen angeht. Wichtig ist wohl auch Unicode-Support fuer diese DLL!
library dll;
uses ShareMem, SysUtils, Classes, Windows, Messages, Controls, Forms, Dialogs, StdCtrls, ExtCtrls; {$R *.res} const REGROOT = 'Software\\bdaehn\\SoftCopy'; type SCJOBINFO = record formName: Array[0..32-1] of CHAR; printQuality: Integer; colorType: Integer; jpegQuality: Integer; tiffCompression: Integer; tiffQuality: Integer; pdfQuality: Integer; end; type SCFILEINFO = record name: Array[0..MAX_PATH-1] of WCHAR; ext: Array[0..MAX_PATH-1] of WCHAR; typ : Integer; end; function scGetJobInfo(var test: SCJOBINFO):Bool; begin // ShowMessage('buh'); Result:=True; end; function scGetSaveFilename(var test: SCFILEINFO):Bool; begin //ShowMessage('buh'); Result:=True; end; function scEndOfJob():Bool; begin // ShowMessage('buh'); Result:=True; end; begin end. Attached ist noch ein Beispiel in C++ ... Vielen Dank und Gruss /bjoern |
Re: Win32 DLL erstellen
Code:
Dies entspricht:
typedef BOOL (WINAPI *SCGETJOBINFOFUNC) (SCJOBINFO*);
typedef BOOL (WINAPI *SCGETSAVEFILENAMEFUNC) (SCFILEINFO*); typedef void (WINAPI *SCENDOFJOBFUNC) ();
Delphi-Quellcode:
Viel Erfolg!
type
SCGETJOBINFOFUNC = function(var bla: SCJOBINFO): BOOL; stdcall; SCGETSAVEFILENAMEFUNC = function(var bla:SCFILEINFO):BOOL; stdcall; SCENDOFJOBFUNC = procedure(); stdcall; Es handelt sich also nur um Typendeklarationen für Funktionspointer. Nicht jedoch um statische Importe!!! Noch'n Nachtrag: stdcall ist hier ganz wichtig. Delphi übergibt, wie bei VC's fastcall die Parameter zuerst in den Registern und dann auf dem Stack. stdcall benutzt ab dem ersten Parameter den Stack. WINAPI impliziert stdcall! |
Re: Win32 DLL erstellen
Versuch's mit der Übersetzung (bei Unicode musst Du noch 'UNICODE' definieren)
Delphi-Quellcode:
type
TScColorType = type Longint; const SC_OUTPUT_BLACKWHITE = TScColorType(1); SC_OUTPUT_GRAYSCALE = TScColorType(2); SC_OUTPUT_COLOR = TScColorType(3); type TScTiffCompression = type Longint; const SC_TIFTYPE_NONE = TScTiffCompression(1); SC_TIFTYPE_PACKBITS = TScTiffCompression(2); SC_TIFTYPE_CCITT_HUFFMAN = TScTiffCompression(3); SC_TIFTYPE_CCITT_T4 = TScTiffCompression(4); SC_TIFTYPE_CCITT_T6 = TScTiffCompression(5); SC_TIFTYPE_JPEG = TScTiffCompression(6); type PScJobInfoA = ^TScJobInfoA; TScJobInfoA = packed record formName : array [0..31] of AnsiChar; printQuality : Longint; colorType : TScColorType; jpegQuality : Longint; tiffCompression: TScTiffCompression; tiffQuality : Longint; pdfQuality : Longint; end; PScJobInfoW = ^TScJobInfoW; TScJobInfoW = packed record formName : array [0..31] of WideChar; printQuality : Longint; colorType : TScColorType; jpegQuality : Longint; tiffCompression: TScTiffCompression; tiffQuality : Longint; pdfQuality : Longint; end; PScJobInfo = ^TScJobInfo; {$IFDEF UNICODE} TScJobInfo = TScJobInfoW; {$ELSE} TScJobInfo = TScJobInfoA; {$ENDIF} type TScFileType = type Longint; const SC_BMP = TScFileType(1); SC_PNG = TScFileType(2); SC_JPG = TScFileType(3); SC_TIF_SINGLE = TScFileType(4); SC_PDF_SINGLE = TScFileType(5); SC_TIF_MULTIPLE = TScFileType(6); SC_PDF_MULTIPLE = TScFileType(7); type TScFileInfo = packed record name : array [0..MAX_PATH-1] of WideChar; ext : array [0..MAX_PATH-1] of WideChar; type_: TScFileType; end; type TFNScGetJobInfoFunc = function(var TScJobInfo): BOOL; stdcall; // scGetJobInfo TFNScGetSaveFileNameFunc = function(var TScFileInfo): BOOL; stdcall; // scGetSaveFileName TFNScEndOfJobFunc = procedure; stdcall; // scEndOfJobFunc Zitat:
Nimm alles aus der Uses-Liste raus was Du nichts brauchst (ShareMem hat in Deiner DLL nichts zu suchen!). |
Re: Win32 DLL erstellen
Hallo!
Vielen Dank fuer die echt schnell Hilfe! Ich habe beide Loesungsansaetze probiert - leider noch immer gleicher Effekt - bekomme 3 spoolsv.exe application errors: "The instruction at "0x00000000" referenced memory at "0x00000000:. The memory could not be "read". Ich wuerde einmal auf ein Problem mit den Uebergabe-Parametern tippen... Ich habe auch in anderen dll-Beispielen gesehen, dass dort "exports" benutzt wird, um die Symbole/Funktionen zu exportieren - koennte das evtl. ein Problem sein? Muss man bei einer DLL nicht auch nicht eine Funktion fuer die dll-Einstiegspunkte setzen? Also etwas in der Art?
Delphi-Quellcode:
Vielen Dank
BOOL APIENTRY DllMain(HANDLE hModule, DWORD ul_reason_for_call, LPVOID lpReserved)
{ switch (ul_reason_for_call) { case DLL_PROCESS_ATTACH: case DLL_THREAD_ATTACH: case DLL_THREAD_DETACH: case DLL_PROCESS_DETACH: break; } return TRUE; } /bjoern |
Re: Win32 DLL erstellen
Zitat:
Zitat:
Zitat:
Delphi-Quellcode:
am Ende.
begin
end. |
Re: Win32 DLL erstellen
Sorry, hatte den letzten Absatz in Deiner Antwort schlichtweg uebersehen!
Nachdem ich exports hinzugefuegt habe und die uses-Klausel bereinigt habe, scheint die dll halbswegs zu funktionieren - zumindest wird beim 1. Aufruf der dll (nachdem der print-service neugestartet wurde) die Funktion "scGetJobInfo()" aufgerufen (anschliessend allerdings nicht mehr, aber das kann auch so gewollt sein; muss ich noch einmal genauer untersuchen) und zum Schluss immer "scEndJob()". "scGetSaveFilename()" wird scheint hingegen wohl nie ausgerufen zu werden... Ist denn die Uebersetzung von z.B.
Delphi-Quellcode:
in
BOOL WINAPI scGetSaveFileName(SCFILEINFO* info)
Delphi-Quellcode:
korrekt - oder muss man hier auch Pointer uebergeben?
function scGetSaveFilename(var test: TScFileInfo):Bool;
Btw. was macht eigentlich ?
Delphi-Quellcode:
Denke, dass das wohl die Art und Weise beinflusst, die die Library gelinkt wird - oder?
TFNScGetJobInfoFunc = function(var TScJobInfo): BOOL; stdcall;
Gruss /bjoern |
Re: Win32 DLL erstellen
Zitat:
Zitat:
Delphi-Quellcode:
Nebenbei:
function scGetSaveFilename(var test: TScFileInfo): LongBool; stdcall;
Delphi-Quellcode:
ist intern das gleiche wie
function scGetSaveFilename(ScFileInfo: PScFileInfo): LongBool; stdcall;
Delphi-Quellcode:
Nur, dass man sich bei letzterem darauf verlassen kann, dass die Adresse der Struktur immer gültig ist. Wenn dies nicht der Fall sein sollte (sieht in dem Quellcode nicht danach aus), dann sollte man die erste Varinate der Überszung (mit Pointer) vorziehen und zuerst den Pointer prüfen bevor man die Struktur benutzt...
function scGetSaveFilename(var ScFileInfo: TScFileInfo): LongBool; stdcall;
Zitat:
Gruß Nico |
Re: Win32 DLL erstellen
Hallo!
So sieht der Code nun im Moment aus - hab's sowohl mit Pointern als auch mit Referenzen (var) probiert - immer dergleiche Effekt ( getjobinfo() wird ab und zu mal aufgerufen, getsavefilename() nie und endofjob() immer) - in meinem Demo greife ich auch ueberhaupt noch gar nicht auf die Uebergabewerte zu - gebe ja nur eine Message aus - deshalb denke ich nicht, dass es mit den Uebergabeparametern was zu tun hat. Noch irgendeine Idee, was faul sein koennte? Habe mit einer in Visual C++ geschriebenen DLL ueberprueft, dass wirklich alle 3 Funkionen aufgerufen werden...
Delphi-Quellcode:
Vielen Dank und Gruss
library softcopyex;
uses Windows,Dialogs; {$R *.res} {$DEFINE UNICODE} type TScColorType = type Longint; const SC_OUTPUT_BLACKWHITE = TScColorType(1); SC_OUTPUT_GRAYSCALE = TScColorType(2); SC_OUTPUT_COLOR = TScColorType(3); type TScTiffCompression = Longint; const SC_TIFTYPE_NONE = TScTiffCompression(1); SC_TIFTYPE_PACKBITS = TScTiffCompression(2); SC_TIFTYPE_CCITT_HUFFMAN = TScTiffCompression(3); SC_TIFTYPE_CCITT_T4 = TScTiffCompression(4); SC_TIFTYPE_CCITT_T6 = TScTiffCompression(5); SC_TIFTYPE_JPEG = TScTiffCompression(6); type PScJobInfoA = ^TScJobInfoA; TScJobInfoA = packed record formName : array [0..31] of AnsiChar; printQuality : Longint; colorType : TScColorType; jpegQuality : Longint; tiffCompression: TScTiffCompression; tiffQuality : Longint; pdfQuality : Longint; end; PScJobInfoW = ^TScJobInfoW; TScJobInfoW = packed record formName : array [0..31] of WideChar; printQuality : Longint; colorType : TScColorType; jpegQuality : Longint; tiffCompression: TScTiffCompression; tiffQuality : Longint; pdfQuality : Longint; end; {$IFDEF UNICODE} TScJobInfo = TScJobInfoW; {$ELSE} TScJobInfo = TScJobInfoA; {$ENDIF} PScJobInfo = ^TScJobInfo; type TScFileType = type Longint; const SC_BMP = TScFileType(1); SC_PNG = TScFileType(2); SC_JPG = TScFileType(3); SC_TIF_SINGLE = TScFileType(4); SC_PDF_SINGLE = TScFileType(5); SC_TIF_MULTIPLE = TScFileType(6); SC_PDF_MULTIPLE = TScFileType(7); type PScFileInfo = ^TScFileInfo; TScFileInfo = packed record name : array [0..MAX_PATH-1] of WideChar; ext : array [0..MAX_PATH-1] of WideChar; type_: TScFileType; end; function scGetJobInfo(var test: TScJobInfo):LongBool; stdcall; var temp : String; begin ShowMessage('GetJobInfo()'); Result:=True; end; function scGetSaveFilename(var test: TScFileInfo):LongBool; stdcall; var temp : String; begin ShowMessage('scGetSaveFilename()'); Result:=True; end; procedure scEndOfJob(); stdcall; begin ShowMessage('scEndOfJob()'); end; exports scGetJobInfo, scGetSaveFilename, scEndOfJob; begin end. /bjoern |
Re: Win32 DLL erstellen
Ohne die DLL dürfte ab diesem Punkt eine Analyse des Fehlers schwer werden :-\
|
Re: Win32 DLL erstellen
Zitat:
ps: die Unit Dialogs um eine Nachricht anzuzeigen ist ziemlicher Overhead, nimm einfach MessageBox :) |
Alle Zeitangaben in WEZ +1. Es ist jetzt 14:41 Uhr. |
Powered by vBulletin® Copyright ©2000 - 2025, Jelsoft Enterprises Ltd.
LinkBacks Enabled by vBSEO © 2011, Crawlability, Inc.
Delphi-PRAXiS (c) 2002 - 2023 by Daniel R. Wolf, 2024-2025 by Thomas Breitkreuz