IDirect3DDevice9: Nicht aufgelöstes Token
-
Hi,
Ich hab ein Problem mit meinem C++-Code:// ScreenCapture.cpp: Hauptprojektdatei. #include "stdafx.h" #include <Windows.h> #include <stdio.h> #include <iostream> #include <string> #include <d3dx9.h> #pragma comment(lib, "d3dx9.lib") #pragma comment(lib, "user32.lib") using namespace std; extern IDirect3DDevice9* g_pd3dDevice; int main(array<System::String ^> ^args) { IDirect3DSurface9* pSurface; int ScreenWidth = GetSystemMetrics(SM_CXSCREEN); int ScreenHeight = GetSystemMetrics(SM_CYSCREEN); g_pd3dDevice->CreateOffscreenPlainSurface(ScreenWidth, ScreenHeight, D3DFMT_A8R8G8B8, D3DPOOL_SCRATCH, &pSurface, NULL); g_pd3dDevice->GetFrontBufferData(0, pSurface); D3DXSaveSurfaceToFile("C:\\tmp\\Bf3Desktop.bmp",(D3DXIMAGE_FILEFORMAT)0,pSurface,NULL,NULL); pSurface->Release(); }
Er soll eigentlich ein Bild von einer DirectX-Anwendung aufnehmen, aber es erscheinen folgende Fehler in der Konsole:
1>------ Erstellen gestartet: Projekt: ScreenCapture, Konfiguration: Debug Win32 ------ 1> ScreenCapture.cpp 1>ScreenCapture.obj : error LNK2020: Nicht aufgelöstes Token (0A000351) "struct IDirect3DDevice9 * g_pd3dDevice" (?g_pd3dDevice@@3PAUIDirect3DDevice9@@A). 1>ScreenCapture.obj : error LNK2001: Nicht aufgelöstes externes Symbol ""struct IDirect3DDevice9 * g_pd3dDevice" (?g_pd3dDevice@@3PAUIDirect3DDevice9@@A)". 1>C:\Users\Marvin\documents\visual studio 2010\Projects\ScreenCapture\Debug\ScreenCapture.exe : fatal error LNK1120: 2 nicht aufgelöste externe Verweise. ========== Erstellen: 0 erfolgreich, Fehler bei 1, 0 aktuell, 0 übersprungen ==========
Warum lässt sich der Code nicht kompilieren? Könnt ihr mir das sagen?
Danke schon im Voraus
-
terbaik schrieb:
Warum lässt sich der Code nicht kompilieren?
Er kann compiliert werden. Das ist ein Linkerfehler. Dieser beschwert sich, dass er das in Zeile 14 deklarierte pd3dDevice nicht finden kann. Die Frage ist: Wo ist es? Da du den Code geschrieben hast, musst du die Antwort darauf selber wissen und dann die entsprechende Objektdatei/Bibliothek dazu linken.
-
Compiliert doch wunderbar, das Problem kommt erst beim Linken.
Und das daher, weil dug_pd3dDevice
nur deklarierst aber nie definierst.Eine Deklaration gibt das Ding bekannt, die brauchst du also in allen .cpp Files wo du darauf zugreifen willst.
Eine Definition erzeugt das Ding dann, d.h. die darf nur 1x vorkommen, muss aber eben auch 1x vorkommen.
Um aus der Deklaration eine Definition zu machen musst du in diesem Fall einfach nur ein
= 0
anhängen.
-
Hallo terbaik,
du hast auch das falsche Projekt erzeugt. Du solltest im VS "Win32 Konsolenprojekt" wählen (und nicht ein C++/CLI Projekt).
-
Nur so zur Info, das ist kein C++, sondern C++/CLI. Das sind unterschiedliche Sprachen!
~edit: Mal wieder zu langsam~
-
Aus Interesse: Was ist der Unterschied zwischen C++ und C++/CLI und wie unterscheidet sich ein CLR-Konsolenprojekt von einem Win32-Konsolenprojekt?
-
hustbaer schrieb:
Compiliert doch wunderbar, das Problem kommt erst beim Linken.
Und das daher, weil dug_pd3dDevice
nur deklarierst aber nie definierst.Eine Deklaration gibt das Ding bekannt, die brauchst du also in allen .cpp Files wo du darauf zugreifen willst.
Eine Definition erzeugt das Ding dann, d.h. die darf nur 1x vorkommen, muss aber eben auch 1x vorkommen.
Um aus der Deklaration eine Definition zu machen musst du in diesem Fall einfach nur ein
= 0
anhängen.Also ich habe den Code nach diesem Tutorial hier geschrieben:
http://www.codeproject.com/Articles/5051/Various-methods-for-capturing-the-screen
Bist du dir sicher, dass man
g_p3dDevice
noch definieren muss? Es ist ein pointer!
-
C++/CLI ist ein C# im C++-Gewand mit etwas interop-Unterstützung.
Eigentlich ist es nur dafür gedacht, Native-C++ mit der Managed-Welt zusammenzubringen, also um Zwischenschichten zu definieren, nicht aber um damit eigenständige Projekte hochzuziehen.
-
Decimad schrieb:
C++/CLI ist ein C# im C++-Gewand mit etwas interop-Unterstützung.
Eigentlich ist es nur dafür gedacht, Native-C++ mit der Managed-Welt zusammenzubringen, also um Zwischenschichten zu definieren, nicht aber um damit eigenständige Projekte hochzuziehen.Also quasi nur Matsch
-
terbaik schrieb:
Bist du dir sicher, dass man
g_p3dDevice
noch definieren muss? Es ist ein pointer!Unabhängig davon dass das kein C++ sondern C++/CLI ist: Du hast die Variable nur deklariert, nicht definiert, denn genau das ist, was das Schlüsselwort extern macht...
-
dot schrieb:
terbaik schrieb:
Bist du dir sicher, dass man
g_p3dDevice
noch definieren muss? Es ist ein pointer!Unabhängig davon dass das kein C++ sondern C++/CLI ist: Du hast die Variable nur deklariert, nicht definiert, denn genau das ist, was das Schlüsselwort extern macht...
Das ganze mit einem Win32-Konsolenprojekt zu machen löst das Problem leider auch nicht
-
terbaik schrieb:
Bist du dir sicher, dass man
g_p3dDevice
noch definieren muss?codeproject.com schrieb:
In the above, g_pd3dDevice is an IDirect3DDevice9 object, and has been assumed to be properly initialized.
-
Oh, wo steht DAS denn Mist
Wie initialisiere ich es also dann?
-
Dieser Thread wurde von Moderator/in SeppJ aus dem Forum C++ (auch C++0x und C++11) in das Forum Spiele-/Grafikprogrammierung verschoben.
Im Zweifelsfall bitte auch folgende Hinweise beachten:
C/C++ Forum :: FAQ - Sonstiges :: Wohin mit meiner Frage?Dieses Posting wurde automatisch erzeugt.
-
Wenn es dir nur darum geht einen Screenshot zu machen, dann würde ich empfehlen, einfach GDI zu verwenden. Per
CreateDC("DISPLAY", nullptr, nullptr, nullptr);
einen Device Context für den ganzen Bildschirm holen, rausblitten und fertig...
-
dot schrieb:
Wenn es dir nur darum geht einen Screenshot zu machen, dann würde ich empfehlen, einfach GDI zu verwenden. Per
CreateDC("DISPLAY", nullptr, nullptr, nullptr);
einen Device Context für den ganzen Bildschirm holen, rausblitten und fertig...- Was heißt rausblitten?
- Kann man mit GDI auch von DirectX-Anwendungen aufnehmen?
-
terbaik schrieb:
- Was heißt rausblitten?
http://msdn.microsoft.com/en-us/library/dd183370.aspx
terbaik schrieb:
- Kann man mit GDI auch von DirectX-Anwendungen aufnehmen?
Es wird das gleiche drauf sein wie wenn du per Hand mit Windows einen Screenshot machst, gleich wie bei der Direct3D Variante auch. Einen Screenshot von einer Fullscreen Direct3D Anwendung wirst du mit beiden Lösungen nicht hinbekommen, denk ich, dafür müsstest du einen Direct3D Hook in die jeweilige Anwendung setzen und direkt an der Quelle das Bild abgreifen...
-
Nein, die DirectX-Methode, mit der ich das Ganze realisieren will, liest das Surface vom Backpuffer der DirectX-Anwendung, dafür braucht man keinen Hook!
-
Kann es denn wirklich so schwer sein, diesen dummen Fehler zu beheben? Kann mir nicht einer von euch sagen, was ich falsch mache? Ihr habt meinen Code, ihr habt die Fehlermeldungen und ihr kennt euch sehr gut mit der C++-Programmierung aus und weil dieser Thread in die Gaming-Kategorie verschoben wurde, nehm ich auch an, dass ihr Ahnung von DirectX habt. Wo liegt das Problem?
-
es wurde dir gesagt, was du zu tun hast. Aber ich schreibs beser mal in all caps: DER COMPILR FINDET DAS OBJEKT NICHT, WEIL DU IHM SAGST, DASS ES IRGENDWO WOANDERS IST, ABER DU ES DANN NIE ERZEUGST.
Also: mach aus dem extern Zeiger einen normalen Zeiger und erstelle dann zuerst das notwendige Device. Dafür sollte man sich aber vorher ein DirectX Tutorial durchlesen.
wenn du extern entfernst ohne das Device zu erstellen, dann compiliert dein Programm und wird erfolgreich gelinkt (wahrscheinlich) aber wird gnadenlos abstürzen.
Vielleicht solltest du auch vorher noch mehr rfahrung mit C++ sammeln. Wer mit Grafikprogrammierung beginnt, sollte keine Probleme mit den Werkzeugen mehr haben.