Anfängerproblem mit DLL-Einbindung, Zeigern und Datentyp-Konvertierung
-
Hallo,
ich muss für ein älteres Prüfsystem, zum Einbinden PCI-CAN-Karte, eine Hilfs-Dll erstellen, mit der ich einige Inkompatibilitäten (struct etc.) umgehen muss. Zum ansprechen der Hardware dient mir eine Dll (GPxi3051w.dll) des Herstellers. Zum testen habe ich erst einmal eine Consolen-Applikation erstellt. Was C(++|#) angeht habe ich (fast) keinerlei Erfahrungen. Hier erst einmal der Code der Cpp-Datei:
#include "stdafx.h" #include "GPxi3051w.h" #include <stdio.h> #include <iostream> using namespace std; int main(int argc, char* argv[]) { GPxi3051_StructDriverInfo DriverInfo; int errornr; errornr= GPxi3051_GetDriverInfo(*DriverInfo); cout <<"Version:" << DriverInfo.Version << "\n"; cout <<"SW_XILINX:" << DriverInfo.SW_XILINX << "\n"; cout <<"GeoAddress:" << DriverInfo.GeoAddress << "\n"; cout <<"SerialNumber:" << DriverInfo.SerialNumber << "\n"; cout <<"Revision:" << DriverInfo.Revision << "\n"; cout <<"Fehler:" << errornr << "\n"; return 0; }und der Code der Header-Datei
#ifndef PXI3051_API_HEADER #define PXI3051_API_HEADER /*------------------------------------------------------------------*/ /* Defines */ /*------------------------------------------------------------------*/ #define DEV_MAX 12 /*------------------------------------------------------------------*/ /* Typedefs */ /*------------------------------------------------------------------*/ typedef struct { unsigned long Version; unsigned long DevCount; unsigned long SW_XILINX[DEV_MAX]; unsigned long GeoAddress[DEV_MAX]; unsigned long SerialNumber[DEV_MAX]; unsigned long Revision[DEV_MAX]; } GPxi3051_StructDriverInfo; /*------------------------------------------------------------------*/ /* Functions */ /*------------------------------------------------------------------*/ int __declspec ( dllexport ) __stdcall GPxi3051_GetDriverInfo(GPxi3051_StructDriverInfo *pDriverInfo); int __declspec ( dllexport ) __stdcall GPxi3051_DLL_Version(unsigned long *pVersion); int __declspec ( dllexport ) __stdcall GPxi3051_ResetPort(unsigned long card, unsigned long port); int __declspec ( dllexport ) __stdcall GPxi3051_DpramWriteInstruction(unsigned char data[], unsigned long length); int __declspec ( dllexport ) __stdcall GPxi3051_DpramReadResponse(unsigned long card, unsigned long port, unsigned char data[], unsigned long *length); int __declspec ( dllexport ) __stdcall GPxi3051_DpramReadMonitor(unsigned long card, unsigned long port,void *data, unsigned long *length); int __declspec ( dllexport ) __stdcall GPxi3051_XilinxDownload(unsigned long card, char *pFileName); int __declspec ( dllexport ) __stdcall GPxi3051_XilinxWriteData(unsigned char data[], unsigned long length); #endifUnd meine drei Probleme
1. Wie wird eine DLL in VC++6 eingebunden? Ich habe keine LIB-Datei, kenne aber die Funktionen (siehe Header-Datei). Ich habe alles was ich im Internet und im MSDN gefunden habe ausprobiert, allerdings ohne Erfolg.
2. Wo finde ich im MSDN oder Internet eine Übersicht über die Konvertierung von Datentypen in C++?
3. Beim Erstellen der Anwendung kommt es zu folgender Fehlermeldung:D:\Users\Pierre\Eigene Dateien\Visual C\can_dll v2\can_dll v2.cpp(16) : error C2100: Zeigeroperation ungueltig D:\Users\Pierre\Eigene Dateien\Visual C\can_dll v2\can_dll v2.cpp(16) : error C2664: 'GPxi3051_GetDriverInfo' : Konvertierung des Parameters 1 von 'GPxi3051_StructDriverInfo' in 'GPxi3051_StructDriverInfo *' nicht möglich Kein benutzerdefinierter Konvertierungsoperator verfügbar, der diese Konvertierung durchführen kann, oder der Operator kann nicht aufgerufen werdenWas habe ich hier Falsch gemacht?
Mit freundlichen Grüßen
PierreOne
-
Versuch mal:
errornr= GPxi3051_GetDriverInfo(&DriverInfo);
-
oder versuch mal :
GPxi3051_StructDriverInfo *DriverInfo;
-
Hallo,
Was ist eigentlich der Unterschied zwischen "GPxi3051_GetDriverInfo(&DriverInfo)" und GPxi3051_GetDriverInfo(*DriverInfo). Natürlich habe ich es ausprobiert, allerdings führte es zu der Fehlermeldung:
Temporäre Dateien und Ausgabedateien für "can_dll v2 - Win32 Debug" werden gelöscht. --------------------Konfiguration: can_dll v2 - Win32 Debug-------------------- Kompilierung läuft... StdAfx.cpp Kompilierung läuft... can_dll v2.cpp Linker-Vorgang läuft... can_dll v2.obj : error LNK2001: Nichtaufgeloestes externes Symbol "int __stdcall GPxi3051_GetDriverInfo(struct GPxi3051_StructDriverInfo *)" (?GPxi3051_GetDriverInfo@@YGHPAUGPxi3051_StructDriverInfo@@@Z) Debug/can_dll v2.exe : fatal error LNK1120: 1 unaufgeloeste externe Verweise Fehler beim Ausführen von link.exe. can_dll v2.exe - 2 Fehler, 0 Warnung(en)Deshalb habe ich mit pexports eine def-Datei erstellt und eingebunden.
LIBRARY GPxi3051w.dll EXPORTS GPxi3051_DLL_Version @1 GPxi3051_DpramReadMonitor @6 GPxi3051_DpramReadResponse @5 GPxi3051_DpramWriteInstruction @4 GPxi3051_GetDriverInfo @2 GPxi3051_ReadWriteSpezial @14 GPxi3051_ResetPort @7 GPxi3051_XilinxDownload @3 GPxi3051_XilinxWriteData @15Die Fehlermeldung lautet dann:
Temporäre Dateien und Ausgabedateien für "can_dll v2 - Win32 Debug" werden gelöscht. --------------------Konfiguration: can_dll v2 - Win32 Debug-------------------- Kompilierung läuft... StdAfx.cpp Kompilierung läuft... can_dll v2.cpp Linker-Vorgang läuft... Bibliothek Debug/can_dll v2.lib und Objekt Debug/can_dll v2.exp wird erstellt can_dll v2.exp : warning LNK4070: Die Direktive /OUT:GPxi3051w.dll in .EXP weicht vom Ausgabedateinamen "Debug/can_dll v2.exe" ab; Direktive wird ignoriert Debug/can_dll v2.exe : warning LNK4086: Einsprungpunkt "_mainCRTStartup" ist nicht __stdcall mit 12 Bytes an Argumenten; Anwendung kann vielleicht nicht ausgefuehrt werden can_dll v2.obj : error LNK2001: Nichtaufgeloestes externes Symbol "int __stdcall GPxi3051_GetDriverInfo(struct GPxi3051_StructDriverInfo *)" (?GPxi3051_GetDriverInfo@@YGHPAUGPxi3051_StructDriverInfo@@@Z) Debug/can_dll v2.exe : fatal error LNK1120: 1 unaufgeloeste externe Verweise Fehler beim Ausführen von link.exe. can_dll v2.exe - 2 Fehler, 2 Warnung(en)Der zweite Vorschlag ist leider ungeeignet, da ich wissen muss ob alles geklappt hat.
MfG
PierreOne
-
du musst auch beim zweiten vorschlage die klammern weg lassen!
GPxi3051_StructDriverInfo *DriverInfo;und zwar will ich nicht das du den * vor DriverInfo bei der Parameter übergabe in der Funktion
errornr= GPxi3051_GetDriverInfo(.....);, sonder
bei der deklaration der DriverInfo (erste zeile bei dir in main)und bei den funktionaufruf schreibst dann:
errornr= GPxi3051_GetDriverInfo(DriverInfo);so mein ich:
#include "stdafx.h" #include "GPxi3051w.h" #include <stdio.h> #include <iostream> using namespace std; int main(int argc, char* argv[]) { GPxi3051_StructDriverInfo *DriverInfo; int errornr; errornr= GPxi3051_GetDriverInfo(DriverInfo); cout <<"Version:" << DriverInfo.Version << "\n"; cout <<"SW_XILINX:" << DriverInfo.SW_XILINX << "\n"; cout <<"GeoAddress:" << DriverInfo.GeoAddress << "\n"; cout <<"SerialNumber:" << DriverInfo.SerialNumber << "\n"; cout <<"Revision:" << DriverInfo.Revision << "\n"; cout <<"Fehler:" << errornr << "\n"; return 0; }
-
Hallo,
das habe ich natürlich sofort ausprobiert, allerdings folgten andere Fehlermeldungen. Ich vermute, dass meine DLL-Einbindung fehlerhaft ist.
Deshalb habe ich noch einmal von vorne begonnen.
Ich habe deshalb mit “dumpbin /exports /out:exports.txt GPxi3051w.dll“ eine exports.txt mit folgendem Inhalt erstellt.Dump of file GPxi3051w.dll File Type: DLL Section contains the following exports for GPxi3051w.dll 00000000 characteristics 4402DFAE time date stamp Mon Feb 27 12:17:02 2006 0.00 version 1 ordinal base 15 number of functions 9 number of names ordinal hint RVA name 1 0 0000133D GPxi3051_DLL_Version 6 1 00001587 GPxi3051_DpramReadMonitor 5 2 00001531 GPxi3051_DpramReadResponse 4 3 000014A6 GPxi3051_DpramWriteInstruction 2 4 000012CF GPxi3051_GetDriverInfo 14 5 00001637 GPxi3051_ReadWriteSpezial 7 6 000015F0 GPxi3051_ResetPort 3 7 00001358 GPxi3051_XilinxDownload 15 8 00001683 GPxi3051_XilinxWriteData Summary 4000 .data 1000 .rdata 1000 .reloc 5000 .textDaraus habe ich dann eine “GPxi3051w.def“ mit folgendem Inhalt erstellt
LIBRARY "GPxi3051w.dll" EXPORTS GPxi3051_DLL_Version @1 GPxi3051_DpramReadMonitor @6 GPxi3051_DpramReadResponse @5 GPxi3051_DpramWriteInstruction @4 GPxi3051_GetDriverInfo @2 GPxi3051_ReadWriteSpezial @14 GPxi3051_ResetPort @7 GPxi3051_XilinxDownload @3 GPxi3051_XilinxWriteData @15Jetzt habe ich ein leeres Consolen-Projekt erstellt die "GPxi3051w.def" und eine Header-Datei mit folgendem Inhalt hizugefügt.
/*------------------------------------------------------------------*/ /* Defines */ /*------------------------------------------------------------------*/ #define DEV_MAX 12 /*------------------------------------------------------------------*/ /* Typedefs */ /*------------------------------------------------------------------*/ typedef struct { unsigned long Version; unsigned long DevCount; unsigned long SW_XILINX[DEV_MAX]; unsigned long GeoAddress[DEV_MAX]; unsigned long SerialNumber[DEV_MAX]; unsigned long Revision[DEV_MAX]; } GPxi3051_StructDriverInfo; /*------------------------------------------------------------------*/ /* Functions */ /*------------------------------------------------------------------*/ #define DllImport __declspec( dllimport ) DllImport int GPxi3051_DLL_Version(unsigned long *pVersion); DllImport int GPxi3051_DpramReadMonitor(unsigned long card, unsigned long port,void *data, unsigned long *length); DllImport int GPxi3051_DpramReadResponse(unsigned long card, unsigned long port, unsigned char data[], unsigned long *length); DllImport int GPxi3051_DpramWriteInstruction(unsigned char data[], unsigned long length); DllImport int GPxi3051_GetDriverInfo(GPxi3051_StructDriverInfo *pDriverInfo); DllImport int GPxi3051_ResetPort(unsigned long card, unsigned long port); DllImport int GPxi3051_XilinxDownload(unsigned long card, char *pFileName); DllImport int GPxi3051_XilinxWriteData(unsigned char data[], unsigned long length);Zur Vollständigkeit auch noch das Programm
#include "stdafx.h" #include "GPxi3051w.h" int main(int argc, char* argv[]) { int errornr; errornr = GPxi3051_ResetPort(1, 1); return TRUE; }Beim erstellen wird folgende Fehlermeldung ausgegeben.
Temporäre Dateien und Ausgabedateien für "tcan - Win32 Debug" werden gelöscht. --------------------Konfiguration: tcan - Win32 Debug-------------------- Kompilierung läuft... StdAfx.cpp tcan.cpp Linker-Vorgang läuft... GPxi3051w.def : error LNK2001: Nichtaufgeloestes externes Symbol GPxi3051_DLL_Version GPxi3051w.def : error LNK2001: Nichtaufgeloestes externes Symbol GPxi3051_DpramReadMonitor GPxi3051w.def : error LNK2001: Nichtaufgeloestes externes Symbol GPxi3051_DpramReadResponse GPxi3051w.def : error LNK2001: Nichtaufgeloestes externes Symbol GPxi3051_DpramWriteInstruction GPxi3051w.def : error LNK2001: Nichtaufgeloestes externes Symbol GPxi3051_GetDriverInfo GPxi3051w.def : error LNK2001: Nichtaufgeloestes externes Symbol GPxi3051_ReadWriteSpezial GPxi3051w.def : error LNK2001: Nichtaufgeloestes externes Symbol GPxi3051_ResetPort GPxi3051w.def : error LNK2001: Nichtaufgeloestes externes Symbol GPxi3051_XilinxDownload GPxi3051w.def : error LNK2001: Nichtaufgeloestes externes Symbol GPxi3051_XilinxWriteData Debug/tcan.lib : fatal error LNK1120: 9 unaufgeloeste externe Verweise LINK : fatal error LNK1141: Fehler bei der Erstellung der Exportdatei Fehler beim Ausführen von link.exe. tcan.exe - 11 Fehler, 0 Warnung(en)Was habe ich falsch gemacht?
Mit freundlichen Grüßen
PierreOne