loadlibrary unter W10
Hallo,
ich muß eine Fremd-DLL unter WIN10 Pro 64Bit per loadLibrary einbinden. Die DLL wird als 32 Bit und 64 Bit Version zur Verfügung gestellt. Mit lastError erhalte ich entweder error = 193 (bad EXE format) oder error = 126 (not found). Die DLL ist vorhanden, das habe ich mit FileExists vorher geprüft und ich verwende loadLibrary(PChar( DLL-NAME )). Ich vermute die DLL benötigt andere DLLs und wird daher nicht geladen. Per HEX-Editor sehe ich (u.a.) MSVCP100.DLL. Als Test versuche ich mit loadLibrary MSVCP100.DLL einzeln zu laden. Das klapp aber auch nicht. Gibt es ein spezielle Version von MSVCP100 für 64 Bit? Ich bin aus den gefundenen Infos nicht schlau geworden. Auf meimem PC finde ich diese DLL nur unter C:\windows\system32, auch nachdem ich eine (angeblich) für 64 gedachet Version nachinstalliert habe. |
AW: loadlibrary unter W10
Ich glaube das Tool das einem anzeigen konnte was beim Einladen einer DLL falsch läuft hieß "Dependency Walker". Das würde ich mal auf die 32 und 64-Bit-Version loslassen und schauen was der ausspuckt.
|
AW: loadlibrary unter W10
.. danke, hab ich schon gemacht. Das Drama dauert schon 4 Tage und ich habe die Details erstmal weggelassen.
Im D.Walker sehe ich auch MSVCP100.DLL. ich verstehe nur nicht, warum ich diese DLL mit LoadLibrary auch nicht laden kann. |
AW: loadlibrary unter W10
Zitat:
|
AW: loadlibrary unter W10
hab ich gemacht, s.o. aber auf meimem PC finde ich diese DLL nur unter C:\windows\system32
|
AW: loadlibrary unter W10
Zitat:
Für welche Plattform kompilierst du dein Programm? Win32 oder Win64 (oder beide)? Wo genau liegt die zu ladende DLL? Für den Fall, dass sie im %SystemRoot%\system32 liegt, und du ein Win32-Programm hast: Bist du dir der Filesystem Redirection bewusst, die dann zuschlägt (durch WOW64)? Und nicht zuletzt: Etwas Code kann vielleicht auch nicht schaden. Grüße Dalai |
AW: loadlibrary unter W10
Hallo,
Zitat:
Ich würde erst mal ein Testprogramm aufsetzen, wo die fremde Dll im eigenen Verzeichnis liegt. Dort wird zuerst gesucht. |
AW: loadlibrary unter W10
Liste der Anhänge anzeigen (Anzahl: 1)
ist schon klar, ich wollte erstmal "klein anfangen"
Code:
Dei beiden DLLs liegen in zwei Verzeichnissen DLL32 bzw DLL64. Das komplette Projekt ist als ZIP angehängt.
unit Load_DLL_Test;
interface uses Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms, Dialogs, StdCtrls; type TfrmTest = class(TForm) Memo1: TMemo; bt32: TButton; bt64: TButton; procedure FormActivate(Sender: TObject); procedure bt32Click(Sender: TObject); procedure bt64Click(Sender: TObject); private public { Public-Deklarationen } end; var frmTest: TfrmTest; implementation {$R *.dfm} procedure TfrmTest.FormActivate(Sender: TObject); begin memo1.Lines.Clear; memo1.Lines.Add('loadLibrary Test; Version vom 13.12.2019 '); memo1.Lines.Add('ADDIPACK DLLs (32/64 bit) müssen in '); memo1.Lines.Add('zwei Verzeichnissen ..\DLL32 bzw. ..\DLL64 liegen'); end; procedure TfrmTest.bt32Click(Sender: TObject); var strName, strHome: string; err : integer; hndl : THandle; begin memo1.Lines.Add(''); hndl := 0; strHome := ExtractFilePath(Application.ExeName); strName := strHome + 'DLL32\ADDIDATA.DLL'; if FileExists(strName) then memo1.Lines.Add('file ' + strName +' exists') else showMessage('DLL 64 bit not found'); hndl := loadLibrary(PCHAR(strName)); err := GetLastError(); memo1.Lines.Add('32 bit ' + IntToStr(hndl) + ' last error ' + intToStr(err)); end; procedure TfrmTest.bt64Click(Sender: TObject); var strName, strHome : string; err : integer; hndl : THandle; begin memo1.Lines.Add(''); hndl := 0; strHome := ExtractFilePath(Application.ExeName); strName := strHome + 'DLL64\ADDIDATA.DLL'; if FileExists(strName) then memo1.Lines.Add('file ' + strName +' exists') else showMessage('DLL 64 bit not found'); hndl := loadLibrary(PCHAR(strName)); err := GetLastError(); memo1.Lines.Add('64 bit ' + IntToStr(hndl) + ' last error ' + intToStr(err)); end; end. Ich arbeite für WIN10 64bit mit Delphi 6, ja ich weiß das ist alt ... |
AW: loadlibrary unter W10
Zitat:
Wenn die DLL dann noch nicht funktioniert, ist das Problem ein anderes. Zitat:
DLL erzeugt mit modernem Delphi und du arbeitest mit einem alten. Das Problem hatte ich umgekehrt schon. |
AW: loadlibrary unter W10
Mit Delphi 6 Programmen kannst Du keine 64-Bit-DLL laden.
|
AW: loadlibrary unter W10
Zitat:
@joacim: Den (relevanten) Fehlercode aus dem OP beschreibt MS so: Zitat:
Grüße Dalai |
AW: loadlibrary unter W10
@samso ich weiß, daß man mit D6 keine 64 bit DLL laden/verwenden kann. Das mache ich alles nur, um jede Möglichkeit auszuschöpfen.
Auf die DLL selber habe ich keinen Einfluß, die kommt vom Hersteller der Mess-Karten, die ich ansprechen soll. Ich denke mal, die DLL ist mit C oder C++ erstellt worden. Ein Kontakt mit dem Hersteller gestaltet sich eher schwierig. |
AW: loadlibrary unter W10
Liste der Anhänge anzeigen (Anzahl: 1)
@Frühlingsrolle In meinem Rechner steckt eine PCIe3021. Das ist aber nicht entscheidend.
Ich habe mit dem "normalen" Treiber schon Programme für die Karte entwickelt. Jetzt geht es um einen neuen sog. Universaltreiber. Ich habe auch eine ausführliche Dokumentation mit allen Aufrufen usw. Die Sache mit dem statischen Linken hatte ich inzwischen schon verwendet und der Treiber liegt auch im Verzeichnois der EXE. Jetzt bekomme ich wenigstens Fehlermeldungem. Erstmal fehlte MSVCR100.DLL (liegt jetzt im Verzeichnis) Dann wurde MSVCP100.DLL nicht gefunden. Das schein ja - nach vielen Hinweisen im Netz - ein übliches Problem zu sein. Ich habe den MS-Installer ausgeführt und sehe MSVCP100.DLL jetzt unter c:\windows\system32. Das scheint aber noch nicht ausreichend zu sein. Beim Start des Programms bekomme ich immer noch eine Fehlermeldung (s. Anhang). Es scheint ja auch noch Probleme mit div. Verssionen der MSVCP100.DLL zu geben ... |
AW: loadlibrary unter W10
Wenn die DLL auf das Vorhandensein der msvc*100.dll angewiesen ist, muss die 32-bit (x86) Version der Visual C++ Redistributable 2010 installiert sein/werden. Deren DLLs landen dann in %SystemRoot%\SysWOW64 (\system32 bitte ignorieren für diesen Fall, weil dort 64-bit DLLs liegen).
Alle (halbwegs) aktuellen Visual C++ Redists können bei MS geladen werden: https://support.microsoft.com/en-us/...al-c-downloads (für die 2010 muss man auf das MFC Update zurückgreifen, wenn man kein MS-Konto hat). Grüße Dalai |
AW: loadlibrary unter W10
Liste der Anhänge anzeigen (Anzahl: 1)
Zitat:
|
AW: loadlibrary unter W10
Die Fehler aus LoadLibrary (ERROR_MOD_NOT_FOUND) können sich halt auf die DLL selbst beziehen, oder auf eine andere abhängige DLL,
oder es kann aus den Startprozeduren der DLLs kommen und da dann z.B. auch von dynamischen Links. Wie bereits genannt wurde, kannst du mit gewissen Programmen die statischen Verlinkungen auflisten und prüfen lassen. Wenn das nichts Hilft, dann entweder mit dem Debugger, der aber nur bei dynamischen Links helfen könnte. Oder z.B. mit einem FileExplorer/ProcessMonitor, welcher die Dateizugriffe loggt. Dort kannst du dann sehen auf welche Dateien und Verzeichnisse zugegriffen und welche davon nicht gefunden wurden. https://docs.microsoft.com/en-us/sys...nloads/procmon Zu den DLLs in Systemverzeichnissen (System32 usw.) brauchst und solltest du kein Verzeichnis beim LoadLibrary und für statische Links angeben. Windows sucht beim hier zuerst in dem Verzeichnis deiner EXE und später auch im "passenden" System-Verzeichnis. (und weiteren Suchpfaden) PS: Du kompilierst ein 32-Bit Programm, also sind für dich nur 32-Bit-DLLs interessant, wie bereits richtig erkannt. (abgesehn von OutOfProcessServern, wo die DLL woanders auch in einem 64-Bit-Host geladen sein kann). Und Achtung, in Windows 64 ist System32 für 64-Bit-DLLs, während die 32-Bit-DLLs im SysWOW64 liegen (System for Windows 32 on Windows 64), aber keine Sorge, denn Windows leitet standardmäßig für dein 32-Bit-Programm auf WoW64 um, falls dein Programm doch einmal auf C:\Windows\System32\... zuzugreifen versucht. Selbiges Umleitungskonzept gilt auch für einige Verzeichnisse in der Registry. Und was das WinSxS (Side-by-Side) betrifft, können Andere es besser erklären, aber im Grunde geht es darum, dass man in seiner Anwendung die DLL-Version vorgeben kann und Windows dann im System unter all den gleichnamigen DLLs die Passende für dich raussucht. https://en.wikipedia.org/wiki/Side-by-side_assembly Vorallem für gewisse System-DLLs ingoniert Windows gleichnamige DLLs in deinem Verzeichnis oder anderen Suchfragen und geht dennoch auf System32. (Sicherheitsdinges, um billige Hooks zu umgehen) aber ist hier egal. Und nun noch etwas Werbung: https://www.embarcadero.com/delphi-starter-edition |
AW: loadlibrary unter W10
guten abend und danke für die vielen Tips!
@dieDolly : Nachdem ich die Installation aus Deiner 7z-Datei verwendet habe, startet mein Testprogramm schon mal ohne Fehlermeldung. Das habe ich bei diversen Versuchen mit anderen Installern für MSVCP100 nicht geschafft. Also nochmal danke! Für die weitere Programmierung brauche ich nun das handle, welches die Treiber-DLL bei LoadLIbrary zurückliefert. Das war ja der Ausgangspunkt. LoadLibrary läuft jetzt zwar durch und liefert (angeblich) auch ein handle (268435456). Das kommt mir aber merkwürdig vor. Außerdem liefert ein GetLastError als Ergenis eine 5 (access denied). Der Versuch diese Handle in einer der DLL-Funktionen zu verwenden liefert dann auch gleich wider einen Fehler. (Externe exception E06D7363). |
AW: loadlibrary unter W10
Zitat:
Zitat:
Bei sowas niemals runterladen! Stattdessen einfach hier nachfragen, wo diese DLL herkommt und was man braucht, damit alles funktioniert. |
AW: loadlibrary unter W10
Zitat:
Das hat aber nichts mit dem Handle zu tun, das du an eine der Funktionen der DLL übergeben kannst (in den Beispielen z.B. ph_DeviceHandle genannt). |
AW: loadlibrary unter W10
Nach verschidenen Tests bekomme ich jetzt die ersten Ergenisse. Versuche die Funktionen des Treibers
zu verwenden, klappten aber immer noch nicht. Das Problem lag in einer fehlenden FAR Deklaration beim Import der Funktionen. @jaenicke Es gibt aber immer noch Unklarheiten. Die Funktionen des Treibers verlangen im Aufruf ein Handle. Ich habe bisher gedacht (und es bei dem Vorläuferprojekt auch so gemacht), das dort das Handle eingetragen werden muss, dass bei LoadLibrary zurückkommt. Das funktioniert zwar, aber ich kann genauso gut Null eintragen und bekomme z.B. sinnvolle Ergebnisse beim Lesen der digitalen Eingänge. Ich erwarte nicht, diese Eigenschaft hier zu klären, da werde ich mal mit dem Hersteller Kontakt aufnehmen. Nachdem nun die größten Hürden genommen sind, kann ich mit der eigentlichen Verwendung des Treibers beschäftigen. Nochmals denke an alle und schon mal frohe Weihnachten. |
AW: loadlibrary unter W10
Zitat:
Sicher, wenn du da vorher deinen Handle-Wert hineinpackst, wird der einfach überschrieben, deshalb merkst du das ohne es zu debuggen nicht. |
AW: loadlibrary unter W10
Ich habe hier - nur als Beispiel - zwei Funktionen
Delphi-Quellcode:
Wie schon geschrieben, wurde im Vorläuferprojekt immer das Handle an die Funktion übergeben.
function b_ADDIDATA_GetNumberOfDigitalInputs(dw_DeviceHandle : DWord; var w_NumberOfChannels : word) : byte; far; stdcall; external 'ADDIDATA.DLL';
function b_ADDIDATA_Read4DigitalInputs(dw_DeviceHandle : DWord; b_port : byte; var b_portValue : byte) : byte; far; stdcall; external 'ADDIDATA.DLL'; Die beiden Funktionen erwarten auch hier die Übergabe von dw_DeviceHandle, nicht als var, also nicht als Rückgabewert! In der Dokumentation steht z.B. <return value> = b_ADDIDATA_Read4DigitalInputs(DWORD dw_DeviceHandle, BYTE b_port : byte, PBYTE pb_portValue) Ich interpretiere PBYTE als Pointer auf ein Byte, daher VAR im Delphi. dw_DeviceHandle ist aber DWORD also kein VAR, also auch kein Rückgabewert. Warum ist es völlig gleichgültig, was ich da übergebe? Das Lesen der digitalen Eingänge funktioniert jerdenfalls, auch mit dw_DeviceHandle = 0. Die Antwort kann wahrscheinlich nur der Hersteller geben. |
AW: loadlibrary unter W10
DeviceHandle! Das Handle des Geräts und nicht das Handle der DLL. Die Funktion muss ja wissen von welchem Gerät du die Infos willst.
|
AW: loadlibrary unter W10
Zitat:
|
AW: loadlibrary unter W10
@jaeinicke
Der Aufruf von i_ADDIDATA_OpenWin32Driver liefert als Handle immer Null zurück. Die Aufrufe der anderen Funktionen, die das Handle benötigen, funktionieren aber, wenn ich dort diese Null eintrage. Ich hätte für ein Handle eigentlich einen Wert ungleich Null erwartet Mit Euren Hilfen und Anregungen habe ich jetzt die wichtigsten Dinge zum Laufen gebracht, frage mich aber immer noch, warum das Handle Null ist. |
AW: loadlibrary unter W10
Doku zu i_ADDIDATA_OpenWin32Driver
... -Output PDWORD pdw_DriverHandle Returns the driver handle. This parameter i the first to be called up for each function. Soweit so klar, trotzdem würde ich da keine Null erwarten. |
AW: loadlibrary unter W10
hab ich gemacht, kommt aber nur eine große Zahl als Fehlercode, die in keiner Liste steht.
Das ist auch nicht weiter verwunderlich, weil i_ADDIDATA_OpenWin32Driver mit Null ( = kein Fehler) zurückkommt. |
Alle Zeitangaben in WEZ +1. Es ist jetzt 02:03 Uhr. |
Powered by vBulletin® Copyright ©2000 - 2024, Jelsoft Enterprises Ltd.
LinkBacks Enabled by vBSEO © 2011, Crawlability, Inc.
Delphi-PRAXiS (c) 2002 - 2023 by Daniel R. Wolf, 2024 by Thomas Breitkreuz