| Autor |
Beitrag |
crxfreak
Hält's aus hier
Beiträge: 4
|
Verfasst: Fr 20.04.07 10:09
Hallo in die Runde,
ich habe eine Access.dll auf die ich mit einem VB-Programm zugreifen muß.
Nachfolgend der Code mit dem über Delphi auf die DLL zugegriffen wird.
1: 2: 3: 4: 5: 6: 7: 8: 9: 10: 11: 12: 13: 14: 15: 16: 17: 18: 19: 20: 21: 22: 23: 24: 25: 26: 27: 28: 29: 30: 31: 32: 33: 34: 35: 36: 37: 38: 39: 40: 41: 42: 43: 44: 45: 46: 47: 48: 49: 50: 51: 52: 53: 54: 55: 56: 57: 58: 59: 60: 61: 62: 63: 64: 65: 66: 67: 68: 69: 70: 71: 72: 73: 74: 75: 76: 77: 78: 79:
| program ea; {$APPTYPE CONSOLE} uses SysUtils, Windows;
const LibName = 'Access.dll'; var HLib : THandle;
type TGetUGfsPGfs = function (FileName : PChar; var UGfs, PGfs : DWORD) : integer; cdecl; TGetErrorStr = function : PChar; cdecl; TGetVersionNr = function : integer; cdecl; var GetUGfsPGfs : TGetUGfsPGfs; GetErrorStr : TGetErrorStr; GetVersionNr : TGetVersionNr;
UGfs, PGfs : DWORD;
function DWORDToStr(x : DWORD) : string; var i : integer; Mask : DWORD; begin Result := ''; Mask := 1; for i := 1 to 32 do begin if (Mask and x) <> 0 then Result := Result + ' ' + IntToStr(i); Mask := Mask shl 1; end ; end ;
begin if ParamCount = 0 then begin Writeln(Format('Test eds access dll (%s)', [LibName])); Writeln('Usage: ea filename'); end else begin try HLib := LoadLibrary(PChar(LibName)); try if HLib = THandle(0) then raise Exception.Create(Format('Cannot open %s', [LibName]));
GetUGfsPGfs := GetProcAddress(HLib, 'GetUGfsPGfs'); if not Assigned(GetUGfsPGfs) then raise Exception.Create('GetUGfsPGfs not found');
GetErrorStr := GetProcAddress(HLib, 'GetErrorStr'); if not Assigned(GetErrorStr) then raise Exception.Create('GetErrorStr not found');
GetVersionNr := GetProcAddress(HLib, 'GetVersionNr'); if not Assigned(GetVersionNr) then raise Exception.Create('GetVersionNr not found');
Writeln(Format('Lib version Nr: %d', [GetVersionNr]));
if GetUGfsPGfs(PChar(ParamStr(1)), UGfs, PGfs) = 1 then begin Writeln(Format('UGfs: %s', [DWORDToStr(UGfs)])); Writeln(Format('PGfs: %s', [DWORDToStr(PGfs)])); end else raise Exception.Create(StrPas(GetErrorStr));
finally FreeLibrary(HLib); end ; except on E: Exception do begin Writeln('*** ' + E.Message); end; end end ; end. |
Unter VB habe ich die DLL folgendermaßen deklariert...
| Zitat: | | Private Declare Sub GetUGfsPGfs Lib "ACCESS.DLL" (ByRef File As String, ByRef SvrToMacUGfs As Long, ByRef SvrToMacPGfs As Long) |
Wenn ich die Werte an die DLL nach folgendem Schema übergebe...
| Zitat: | | GetUGfsPGfs Dateiname$, Ugfs, Pgfs |
erhalte ich immer die Meldung "Laufzeitfehler '49': Falsche DLL-Aufrufkonvention"
Ich habe schon alle möglichen Datentypen für Ugfs und Pgfs probiert. Hat jemand noch eine Idee für mich?
|
|
ene
      
Beiträge: 779
Erhaltene Danke: 1
Vista, XP, W2K
Delphi, .Net, Deutsch und Englisch
|
Verfasst: Fr 20.04.07 10:21
Hi,
wenns ne Sub ist, sollte es so besser sein:
Quelltext 1:
| GetUGfsPGfs(Dateiname$, Ugfs, Pgfs) |
Vielleicht hilft ein Call davor auch noch. Und du arbeitest hoffentlich im gleichen Modul, sonst wärs als Public ganz nett. Und Sonderzeichen würde ich lieber weglassen.
_________________ Wir, die guten Willens sind, geführt von Ahnungslosen, Versuchen für die Undankbaren das Unmögliche zu vollbringen.
Wir haben soviel mit so wenig so lange versucht, daß wir jetzt qualifiziert sind, fast alles mit Nichts zu bewerkstelligen.
|
|
crxfreak 
Hält's aus hier
Beiträge: 4
|
Verfasst: Fr 20.04.07 10:28
Danke erstmal für die Antwort.
Delphi-Quelltext 1:
| Call GetUGfsPGfs(Dateiname$, Ugfs, Pgfs) |
bringt leider nichts - selber Fehler.
Ja, ist alles in ein und der selben form.
|
|
ene
      
Beiträge: 779
Erhaltene Danke: 1
Vista, XP, W2K
Delphi, .Net, Deutsch und Englisch
|
Verfasst: Fr 20.04.07 11:04
Mach mal bitte eine Funktion draus, mit Subs habe ich in diesem Zusammenhang noch nicht gearbeitet.
_________________ Wir, die guten Willens sind, geführt von Ahnungslosen, Versuchen für die Undankbaren das Unmögliche zu vollbringen.
Wir haben soviel mit so wenig so lange versucht, daß wir jetzt qualifiziert sind, fast alles mit Nichts zu bewerkstelligen.
|
|
alzaimar
      
Beiträge: 2889
Erhaltene Danke: 13
W2000, XP
D6E, BDS2006A, DevExpress
|
Verfasst: Fr 20.04.07 11:11
Die Fehlermeldung ist doch klar und eindeutig: Die Aufrufkonvention der Delphi-DLL ist nicht mit VB kompatibel. Schreib ein 'safecall' (glaub ich) hinter die Prozedurdeklaration in der DLL, so etwa:
Delphi-Quelltext 1:
| Procedure Foobar (Foo : String); safecall |
Außerdem würde ich mit OleVariants arbeiten, bei Strings würde ich nicht die Hand ins Feuer legen, das das auch klappt.
@ene: Prozeduren/SUBs klappen. Das Funktionen auch gehen, wusste ich nicht 
_________________ Na denn, dann. Bis dann, denn.
|
|
ene
      
Beiträge: 779
Erhaltene Danke: 1
Vista, XP, W2K
Delphi, .Net, Deutsch und Englisch
|
Verfasst: Fr 20.04.07 11:21
Wenn man eine DLL hat, die einem auch was zurückgibt, gehts ja nicht anders als über eine Funktion. Und wenn sich etwas nicht mit VB steuern läßt, muss man halt andere Wege gehen.
_________________ Wir, die guten Willens sind, geführt von Ahnungslosen, Versuchen für die Undankbaren das Unmögliche zu vollbringen.
Wir haben soviel mit so wenig so lange versucht, daß wir jetzt qualifiziert sind, fast alles mit Nichts zu bewerkstelligen.
|
|
alzaimar
      
Beiträge: 2889
Erhaltene Danke: 13
W2000, XP
D6E, BDS2006A, DevExpress
|
Verfasst: Fr 20.04.07 12:13
_________________ Na denn, dann. Bis dann, denn.
|
|
ene
      
Beiträge: 779
Erhaltene Danke: 1
Vista, XP, W2K
Delphi, .Net, Deutsch und Englisch
|
Verfasst: Fr 20.04.07 12:27
Find ich "bäh"  Eine Prozedur hat keinen Rückgabeparameter und eine Funktion genau einen. Alles andere wird über Variablen geregelt, aber das ist schon mehr eine philosophische Frage.
_________________ Wir, die guten Willens sind, geführt von Ahnungslosen, Versuchen für die Undankbaren das Unmögliche zu vollbringen.
Wir haben soviel mit so wenig so lange versucht, daß wir jetzt qualifiziert sind, fast alles mit Nichts zu bewerkstelligen.
|
|
alzaimar
      
Beiträge: 2889
Erhaltene Danke: 13
W2000, XP
D6E, BDS2006A, DevExpress
|
Verfasst: Fr 20.04.07 12:33
ene hat folgendes geschrieben: | Find ich "bäh" Eine Prozedur hat keinen Rückgabeparameter |
Was?
ene hat folgendes geschrieben: | | und eine Funktion genau einen. Alles andere wird über Variablen geregelt, aber das ist schon mehr eine philosophische Frage. |
Äh.. Variablen? Du meinst dochg sicherlich VAR Parameter, alles andere wäre 'bäh'? Aber wenn es genau ein Rückgabewert ist, hast Du natürlich Recht, da nehme ich dann auch eine Funktion. Ehrlich gesagt wusste ich nicht, das auch Funktionsaufrufe kompatibel sind (zwischen VB, Delphi, C etc.), wenn es nicht gerade um Basistypen geht.
_________________ Na denn, dann. Bis dann, denn.
|
|
crxfreak 
Hält's aus hier
Beiträge: 4
|
Verfasst: Fr 20.04.07 12:43
Ich bin noch über einen Beitrag gestolpert...
pscode.com/vb/script...d=49776&lngWId=1
Offensichtlich werden werden C - DLLs nicht richtig von VB unterstützt.
Hat da jemand schonmal was von gehört - ich arbeite zum ersten mal mit VB und C, sonst immer mit VB + Cobol.
Hier noch der kurze Erklärungstext den ich erhalten habe...
Delphi-Quelltext 1: 2: 3: 4: 5: 6: 7: 8: 9: 10: 11: 12: 13: 14:
| The test application uses run-time dynamic linking. You will have to implement this in your application: DWORD SvrToMacUGfs = 0; DWORD SvrToMacPGfs = 0; DWORD U,P; for each file listed in the SvrToMac file |
|
|
ene
      
Beiträge: 779
Erhaltene Danke: 1
Vista, XP, W2K
Delphi, .Net, Deutsch und Englisch
|
Verfasst: Fr 20.04.07 12:44
Ist halt philosophisch und solange man nicht gerade mit NullStrings arbeitet, macht auch VB i.d.R. mit. Meine DLL ist nur für die Steuerung einer Zählerkarte und da gibts neben der Initialisierung und dem Kill nur 1 Wert, den ich auslesen will und die anderen beiden sind Bool. Aber nun genug Philosophie 
_________________ Wir, die guten Willens sind, geführt von Ahnungslosen, Versuchen für die Undankbaren das Unmögliche zu vollbringen.
Wir haben soviel mit so wenig so lange versucht, daß wir jetzt qualifiziert sind, fast alles mit Nichts zu bewerkstelligen.
|
|
crxfreak 
Hält's aus hier
Beiträge: 4
|
Verfasst: Fr 20.04.07 13:25
ähm Nullstrings...
Hab ich ganz vergessen mit rein zuschreiben.
| Zitat: |
Access dll interface
-----------------------
The Access dll allows to read the UGfs and PGfs values of a specified EDS file.
The library exports 3 routines.
GetUGfsPGfs
-----------
The GetUGfsPGfs function reads the UGfs and PGfs values out of a specified
file.
int __cdecl GetUGfsPGfs(LPSTR FileName, PDWORD UGfs, PDWORD PGfs);
Parameters:
FileName [in] pointer to a null terminated string with the file name.
UGfs [out] pointer to a DWORD to receive the UGfs value
PGfs [out] pointer to a DWORD to receive the PGfs value
Return value:
The function returns 1 if ok else it returns 0.
GetErrorStr
-----------
The GetErrorStr function retrievs the latest error string. Call GetErrorStr
when GetUGfsPGfs returns 0.
LPSTR __cdecl GetErrorStr(void);
The return value is a pointer to a null terminated error string.
GetVersionNr
------------
The GetVersionNr function returns the Dll version Nr.
int __cdecl GetVersionNr(void); |
|
|
|