Velleman k8055 Konsolenanwendung in VS2013 dll richtig einbinden/verwenden???
-
Mit LoadLibrary und GetProcAddress kannst Du eine DLL laden und deren Einsprungpunkte erhalten.
Depends habe ich dir angeraten um Deine DLL anzuschauen. Dort findest Du nämlich die amen der Einsprungpunkte.
Wenn es nur eine LIB für die Einsprungpunkte der DLL ist, dann spielt es keine Rolle ob diese "alt" oder "neu"ist solange sich der Name der DLL nihct verändert hat und Du keine neuen Funktionen ansprechen wills.
In der LIB stehen nur die Funktionsnamen und der Name der DLL von der diese erfüllt werden.
-
Hallo,
ich habe mir gerade mal das SDK Pack Rev V4.0 heruntergeladen und angeschaut.
Im Ordner 'Examples/K8055DemoBCB' befindet sich eine Header-Datei 'K8055D.h'.
Die anderen Projekte greifen überwiegend dynamisch per LoadLibrary bzw. von .NET aus per P/Invoke (DLLImport) darauf zu.Um von VC aus darauf zuzugeifen, bräuchtest du jedoch am besten die LIB-Datei zur DLL. Jedoch ist die BCB-LIB Datei intern in einem anderen Format (OMF anstatt COFF) und kann daher nicht für den VC verwendet werden.
Probiere doch mal aus, ob du wenigstens das Beispiel 'K8055DemoVC_2008' zum Laufen kriegst (ist zwar C++/CLI, d.h. .NET und für Applikationsentwicklung nicht zu empfehlen), aber dann siehst du ja, ob es technisch läuft.
Ansonsten könntest du auch den Source-Code aus dem Beispiel 'K8055DemoDevC' übernehmen (dieser verwendet aber LoadLibrary, also auch dynamisch und nicht statisch per LIB).
Keine Ahnung warum dort keine LIB für den MSVC dabei ist
-
Hallo,
Danke ich werde weitermachen und versuchen.
Gruß patt
-
Es handelt sich um eine relativ einfache gut dokumentierte DLL.
Den Header kann man aus dem BorlandC-Beispiel übernehmen und die DLL
lässt sich mit LoadLibrary problemlos laden.Hab mir die Exports der DLL aus dem Verzeichnis "DLL_v4.0.0.0" gerade mal
angesehen; sieht so aus:Dump of file K8055D.dll
File Type: DLL
Section contains the following exports for K8055D.dll
00000000 characteristics 0 time date stamp Thu Jan 01 01:00:00 1970 0.00 version 1 ordinal base 24 number of functions 24 number of names ordinal hint RVA name 17 0 0000C488 ClearAllAnalog 12 1 0000C5B4 ClearAllDigital 18 2 0000C448 ClearAnalogChannel 13 3 0000C540 ClearDigitalChannel 23 4 0000C324 CloseDevice 24 5 0000C2B4 OpenDevice 19 6 0000C418 OutputAllAnalog 20 7 0000C3D4 OutputAnalogChannel 6 8 0000C8B0 ReadAll 21 9 0000C3A4 ReadAllAnalog 8 A 0000C844 ReadAllDigital 22 B 0000C368 ReadAnalogChannel 7 C 0000C660 ReadCounter 9 D 0000C77C ReadDigitalChannel 5 E 0000C6B4 ResetCounter 3 F 0000C2AC SearchDevices 15 10 0000C4F0 SetAllAnalog 10 11 0000C640 SetAllDigital 16 12 0000C4B0 SetAnalogChannel 4 13 0000C6EC SetCounterDebounceTime 2 14 0000C2DC SetCurrentDevice 11 15 0000C5D4 SetDigitalChannel 1 16 0000C958 Version 14 17 0000C518 WriteAllDigital
Wenn man sich den Header zum Borland-C ansieht passt es auffallend.
Alle 24 exportierten Funktionen sind namensgleich vorhanden:#ifdef __cplusplus extern "C" { #endif #define FUNCTION __declspec(dllimport) FUNCTION int __stdcall OpenDevice(int CardAddress); FUNCTION void __stdcall CloseDevice(); FUNCTION int __stdcall ReadAnalogChannel(int Channel); FUNCTION void __stdcall ReadAllAnalog(int *Data1, int *Data2); FUNCTION void __stdcall OutputAnalogChannel(int Channel, int Data); FUNCTION void __stdcall OutputAllAnalog(int Data1, int Data2); FUNCTION void __stdcall ClearAnalogChannel(int Channel); FUNCTION void __stdcall ClearAllAnalog(); FUNCTION void __stdcall SetAnalogChannel(int Channel); FUNCTION void __stdcall SetAllAnalog(); FUNCTION void __stdcall WriteAllDigital(int Data); FUNCTION void __stdcall ClearDigitalChannel(int Channel); FUNCTION void __stdcall ClearAllDigital(); FUNCTION void __stdcall SetDigitalChannel(int Channel); FUNCTION void __stdcall SetAllDigital(); FUNCTION bool __stdcall ReadDigitalChannel(int Channel); FUNCTION int __stdcall ReadAllDigital(); FUNCTION int __stdcall ReadCounter(int CounterNr); FUNCTION void __stdcall ResetCounter(int CounterNr); FUNCTION void __stdcall SetCounterDebounceTime(int CounterNr, int DebounceTime); FUNCTION int __stdcall Version(); FUNCTION int __stdcall SearchDevices(); FUNCTION int __stdcall SetCurrentDevice(int CardAddress); #ifdef __cplusplus } #endif
Mit Lib wäre es bequemer, aber es ist alles da was man wirklich brauchen
würde um es mit Visual-Studio in C++ hinzubekommen.Nachtrag:
Eine Funktion fehlt im Borland-Header: ReadAll()
Die meisten Funktionen sind in der Doku mit long statt int deklariert.
(Könnte also sein das man das statt int long verwendet werden muss.)
-
Da hier die Funktionen ziemlich simple sind sollte aus so auch gehen:
https://adrianhenke.wordpress.com/2008/12/05/create-lib-file-from-dll/
-
Hallo,
DANKE für die sehr guten Hinweise und Hilfen.
Ich werde alles mal versuchen.Gruß patt
-
Stimmt, an den "lib"-Befehl hatte ich gar nicht gedacht.
-
Martin Richter schrieb:
... sollte es so auch gehen:
https://adrianhenke.wordpress.com/2008/12/05/create-lib-file-from-dll/Es kommt jedenfalls eine lib raus
LINK : warning LNK4068: /MACHINE nicht angegeben ; Standardwert X86 Bibliothek "K8055D.lib" und Objekt "K8055D.exp" werden erstellt.
-
Während der Ansatz mit LoadLibrary und GetProcAddress problemlos klappt kommt beim Linken gegen die erstellte lib folgende Fehlermeldung:
error LNK2019: Verweis auf nicht aufgelöstes externes Symbol "__imp__OpenDevice@4" in Funktion "_wmain". ... : fatal error LNK1120: 1 nicht aufgelöste externe Verweise.
Die @4 ist in der Lib nicht enthalten.
Version : 0 Machine : 14C (x86) TimeDateStamp: 54AC3679 Tue Jan 06 20:24:41 2015 SizeOfData : 00000017 DLL name : K8055D.dll Symbol name : _OpenDevice Type : code Name type : no prefix Hint : 5 Name : OpenDevice
Wie bekommt man DLL und LIB nun zusammen ?
Bem: Der int als Returnwert für OpenDevice ist übrigens richtig.
-
Das beschriebene Verfahren scheint bei stdcall nicht zu funktionieren.
Ich denke da muss in in der DEF Datei auch das name mangeling berücksichtigen.
-
Martin Richter schrieb:
Das beschriebene Verfahren scheint bei stdcall nicht zu funktionieren.
Ich denke da muss in in der DEF Datei auch das name mangeling berücksichtigen.
Leider müsste es wohl umgekehrt laufen ...
Da man das @x nicht wegbekommt habe ich eine def-Datei mit passenden @ erstellt.
So lässt es sich nun problemlos mit VS linken.
Wenn man aber ein Testprogramm startet wird aber der Einsprungpunkt
"SetCurrentDevice@4" in der DLL nicht gefunden und das Programm wird beendet.Das ist auch nachvollziehbar, da die Funktion ja auch nur ohne @4 in der DLL enthalten ist.
Die def-Datei ohne @4 war also für die DLL bereits völlig richtig.
Wie "überredet" man Visualstudio, das man die @4 nicht braucht ?
Die DLL mir einem Hexeditor ändern wäre ansonsten eine Notlösung. Hoffe das es auch eleganter geht, aber wie ?
-
Dann vermute ich ist es einfacher Dummy Funktionen zu erzeugen und wie hier beschrieben vorzugehen:
http://support.microsoft.com/kb/131313/en-usMit der Header Datei kann man die fehlenden Blöcke ja schnell ergänzen und eine Dummy .c Datei erzeugen.