Forum: PC-Programmierung DLL ungleich DLL


von Martin (Gast)


Lesenswert?

Hallo Leute!


Ich bin gerade dabei, für ein USB-Gerät eine entsprechende Libray zu 
schreiben (Mein erstes C++-Projekt :-)  ).
Ich verwende QT 4.7.0 (32-Bit) für Windows XP.
Sie soll kompatibel für die meisten Entwicklungswerkzeuge (Windows) 
sein. Deshalb soll sie auch als DLL vorliegen.

Ich hab jetzt schon mal eine Test-DLL erstellt und sie in ein neues 
QT-Projekt eingebunden. Kein Problem.

Wenn ich jedoch die DLL in Visual-C++ 2010 Express einbinden möchte, 
habe ich ein Problem.
Folgende Fehler gibt der Linker aus:
test.obj : error LNK2001: Nicht aufgelöstes externes Symbol 
""__declspec(dllimport) public: __thiscall MS::MS::MS(void)" 
(_imp??0MS@MS@@QAE@XZ)".

Jede Methode, die von meiner Library aufgerufen werden sollte, erzeugt 
so eine Meldung.
Die Library habe ich in "Eigenschaften->Linker->Eingabe->Zusätzliche 
Abhängigkeiten" eingetragen. Die DLL habe ich ins Release-Verzeichnis 
des Projektes kopiert.

Ich beschäftige mich damit nun schon 2 Tage und ich komme auf keinen 
grünen Zweig.
Gibt es eine Beschreibung, wie man eine QT-DLL einfach in eine 
Visual-C++-Umgebung einbinden kann?


Vielen Dank im Voraus

Martin

von Rufus Τ. F. (rufus) Benutzerseite


Lesenswert?

Es wird die Importlibrary fehlen, die zur "QT-DLL" gehört.

von Sebastian (Gast)


Lesenswert?

Funktionen von DLLs können verschiedene Aufrufkonventionen haben. Ist 
das "__thiscall" wirklich passend?

von Martin (Gast)


Lesenswert?

Hm, okay.
Ist die Importlibrary in einem entsprechenden Verzeichnis von QT zu 
finden oder muss diese erst durch entsprechende Compilierung erstellt 
werden?

von Martin (Gast)


Lesenswert?

Hi Leute!

Das mit __thiscall kommt vom Visual-C++-Compiler. Leider kenne ich mich 
zu wenig aus ;-)
Ich hab jetzt Folgendes gemacht. Der Einfachheit halber habe ein 
QT-Projekt mit einer statischen DLL angelegt. Soweit ich das verstanden 
habe, existiert nach der Erstellung der Library eine Library-Datei, 
welche mit dem neuen Programm zusammen kompiliert wird.
Ich möchte euch hier dieses kleine Beispiel zeigen, damit wir uns besser 
verständigen können.

Quellcode der Static-Library:
staticlib.cpp
1
#include "staticlib.h"
2
Staticlib::Staticlib() {}
3
int Staticlib::test(int x) const {return x*2;}

staticlib.h
1
#ifndef STATICLIB_H
2
#define STATICLIB_H
3
4
class Staticlib {
5
public:
6
    Staticlib();
7
    int test(int x) const;};
8
9
#endif // STATICLIB_H

Danach habe ich das Ganze mit QT kompiliert. Die Release Datei hat den 
Namen: libstaticlib.a

Nun habe ich ein Visual-C++-Projekt erstellt:
Die Hauptdatei sieht folgendermaßen aus:
1
#include "stdafx.h"
2
#include "stdio.h"
3
#include "staticlib.h"
4
5
int _tmain(int argc, _TCHAR* argv[])
6
{
7
  Staticlib k;
8
  printf("Test. %d",k.test(4));
9
  return 0;
10
}

Wenn ich nun kompiliere, dann erhalte ich folgende Meldung:
1>------ Erstellen gestartet: Projekt: 02stat, Konfiguration: Release 
Win32 ------
1>02stat.obj : error LNK2001: Nicht aufgelöstes externes Symbol 
""public: __thiscall Staticlib::Staticlib(void)" 
(??0Staticlib@@QAE@XZ)".
1>02stat.obj : error LNK2001: Nicht aufgelöstes externes Symbol 
""public: int __thiscall Staticlib::test(int)const " 
(?test@Staticlib@@QBEHH@Z)".
1>C:\test\02stat\Release\02stat.exe : fatal error LNK1120: 2 nicht 
aufgelöste externe Verweise.
========== Erstellen: 0 erfolgreich, Fehler bei 1, 0 aktuell, 0 
übersprungen ==========

Zu dieser Zeit habe ich die Datei libstaticlib.a noch nicht 
miteingebunden, also mache ich das jetzt -> 
"Projekt->Eigenschaften->Linker->Eingabe->Zusätzliche 
Abhängigkeiten->c:\test\02stat\02stat\libstaticlib.a" - okay

Wenn ich nun das Programm starten möchte erhalte ich denselben Fehler, 
wie vorher beschrieben. Es ist also anscheinend egal, ob ich die Library 
einbinde oder nicht. Der Compiler nimmt die Library nach dem Einbinden 
zwar mitauf, aber er kann aus irgendeinem Grund nicht auf die internen 
Funktionen dieser Library zugreifen.

Ich bin über jede Hilfe dankbar.

Schöne Grüße

Martin

von Peter (Gast)


Lesenswert?

Martin schrieb:
> Abhängigkeiten->c:\test\02stat\02stat\libstaticlib.a

ich kenn zwar QT nicht, aber ich hatte bis jetzt unter Windows immer 
.lib Dateien und kein .a - gibt es eventuell bei dir auch eine lib?

von Klaus W. (mfgkw)


Lesenswert?

Man könnte mit dumpbin mal alle Symbole der Lib auflisten lassen.
Dabnn sieht man vielleicht etwas andere Namen als den vermissten
und weiß dann mehr?

von Klaus W. (mfgkw)


Lesenswert?

Peter schrieb:
> kein .a

stimmt, das wird nicht gehen. Falsches Format?

von Martin (Gast)


Lesenswert?

Hi Leute!


Ich hab das jetzt mit "dumpbin" probiert.
dumpbin libstaticlib.a

Ausgabe:
Dump of file libstaticlib.a
File Type: LiBRARY

Summary
0 .bss
0 .data
1C .text

Leider kann ich mit der Ausgabe nichts anfangen. Aber es sieht so aus, 
als sei es eine Library.
Was bedeutet die Ausgabe?

Schöne Grüße, Martin

von Rufus Τ. F. (rufus) Benutzerseite


Lesenswert?

Daß da kein Code in der Library erkannt wird. Im Segment .text steht der 
enthaltene Code, und 0x1C Bytes wäre für eine Library sehr, sehr wenig.

Mit hoher Wahrscheinlichkeit ist das keine vom MS-Linker verdaubare 
Library.

von Martin (Gast)


Lesenswert?

Die Test-Library, die ich oben beschrieben habe ist sehr klein.
Sie enthält eine leere Inline-Konstruktormethode
und eine Methode, die lediglich den Eingangsparameter mit 2 
multipliziert und als Return-Wert zurückgibt.

Diese Library mit H-File habe ich zum Test in ein QT-Projekt 
miteingebunden und dort funktionierts, leider ;-)

von Bob (Gast)


Lesenswert?

Ich vermute das hat garnicht soviel mit der QT zu tun, sondern ist eher 
ein Problem GCC <--> VC++ bzgl. C++ - Code in DLLs.

http://en.wikipedia.org/wiki/Name_mangling#Name_mangling_in_C++

Versuch vielleicht mal eine reine C - Library. Oder ein 'extern "C"' 
aussenrum.

von Klaus W. (mfgkw)


Lesenswert?

Martin schrieb:
> Wenn ich jedoch die DLL in Visual-C++ 2010 Express einbinden möchte,
> habe ich ein Problem.

Kann man damit eigentlich überhaupt reine C++-Projekte erstellen?
Ich habe dunkel im Hinterkopf, daß man damit nur .NET bzw.
managed Code machen kann; vielleicht scheitert es ja daran.
Kann aber auch sein, daß ich mich täusche.
2010 Express hatte ich noch nie in der Hand.

von Peter (Gast)


Lesenswert?

Klaus Wachtler schrieb:
> Kann man damit eigentlich überhaupt reine C++-Projekte erstellen?

ja

von Boris F. (skyperhh)


Lesenswert?

Moin,

also soweit ich das sehe, hast du deine Qt-DLL mit dem MinGW / GCC 
Compiler erstellt ... und willst diese mit dem MSVC++ Compiler nutzen. 
Das geht aber nicht... die DLL muß schon mit dem MSVC++ erstellt werden. 
Deshalb bieten viele Projekte im Netz ihre DLL's in zwei Versionen an, 
einmal für MinGW / GCC und einmal mit MSVC++ kompiliert.

Es ist aber kein Problem, Qt mit dem MSVC++ Compiler zu kompilieren. Du 
mußt nur bei der Installation des Qt Creators MinGW abwählen und danach 
im Creator den MSVC++ auswählen, geht auch mit der Express Version.

Wenn deine DLL Qt-Methoden verwendet, mußt du beim dynamischen linken 
dann auch die Qt-DLLs bereitstellen, beim statischen entfällt das, dafür 
wird die DLL größer.

Abhängigkeiten von DLL's und Programmen kannst du gut auch mit dem Tool 
"dependency walker" überprüfen, war mal Bestandteil von MS, ist jetzt 
aber nicht mehr dabei, ist aber kostenlos im Netz zu bekommen von der 
homepage http://www.dependencywalker.com/

Gruß

Boris

von Rufus Τ. F. (rufus) Benutzerseite


Lesenswert?

Die DLL selbst ist nicht das Problem, aber die Importlibrary. Die muss 
zum jeweils verwendeten Compiler passen.

von Martin (Gast)


Lesenswert?

Gibt es vielleicht eine Möglichkeit, die LIB-Datei zu konvertieren?

Ich habe auch schon Folgendes ausprobiert:
http://jan-stuhlmann.de/include.php?i=tuts/qt/vs2003tut.htm

Dadurch ist es möglich ein QT-Projekt für den Visual C++-Compiler zu 
konvertieren, um es dort später compilieren zu können.
Das Problem bleibt jedoch totzdem bestehen:
Wenn ich also nun ein QT-Projekt konvertiere, welches eine selbst 
erstellte QT-DLL einbindet und ich dieses Projekt dann mit Visual-C++ 
compilieren möchte, habe ich dasselbe Problem, dass die 
Einsprungadressen nicht gefunden werden.

Wenn ich jetzt eine QT-DLL unter QT erstelle ;-)  - gibt es vieleicht 
hierbei die Möglichkeit, dass ich durch einen entsprechenden Parameter 
dem GCC-Compiler sagen kann, dass er eine Lib für Visual erstellen soll?

Schöne Grüße
Martin

von Schorsch (Gast)


Lesenswert?

Martin schrieb:
> Wenn ich jetzt eine QT-DLL unter QT erstelle ;-)  - gibt es vieleicht
> hierbei die Möglichkeit, dass ich durch einen entsprechenden Parameter
> dem GCC-Compiler sagen kann, dass er eine Lib für Visual erstellen soll?

Wie dir oben schon jemand geschrieben hat:

Du kannst deiner ganzen QT-Umgebung beibringen, statt des 
mitgelieferten GCC einfach den MS-Compiler zu benutzen.
Dann ist deine ganze QT, und alle damit verlinkten und "erstellten" DLLs 
VC++-Kompatibel. Aber dann halt nicht mehr GCC-Kompatibel.

von fbi (Gast)


Lesenswert?

Unter gewissen Umständen kann man auch nachträglich aus der Dll noch 
eine Importlibrary erzeugen:
http://support.microsoft.com/kb/131313

Früher (bei Borland immer noch) gabs dafür mal implib.exe

Bitte melde dich an um einen Beitrag zu schreiben. Anmeldung ist kostenlos und dauert nur eine Minute.
Bestehender Account
Schon ein Account bei Google/GoogleMail? Keine Anmeldung erforderlich!
Mit Google-Account einloggen
Noch kein Account? Hier anmelden.