virtual funktion in bibliothek LNK2019
-
Moin,
schreibe im moment http libary möchte diese jetzt auf windows potieren habe nur eine schwerigkeit festgsstellt.
Wenn ich eine virtuelle funktion definiere und diese erst ausserhalb der bibliothek nutzen möchte bekomme ich LNK2019 gibt es die Möglichkeit unter Visualstudio diese extern zu deklarieren so das er keinen linking error mehr erzeugt. Unter clang und gcc geht das Problem los also denke ich gibt auch eine möglichkeit für vs2015.
Der code liegt auf github:
https://github.com/Tuxist/libhttpppSeverity Code Description Project File Line Suppression State Error LNK2019 unresolved external symbol "public: virtual void __cdecl libhttppp::Queue::RequestEvent(class libhttppp::Connection *)" (?RequestEvent@Queue@libhttppp@@UEAAXPEAVConnection@2@@Z) referenced in function "public: __cdecl libhttppp::Queue::Queue(class libhttppp::ServerSocket *)" (??0Queue@libhttppp@@QEAA@PEAVServerSocket@1@@Z) http++ C:\Users\Player\Source\Repos\libhttppp\build_win\src\iocp.obj 1
-
So wie es im Code aussieht, hat dein Problem (noch) nichts mit DLL zu tun. Vielmehr deklarierst du
void libhttppp::Queue::RequestEvent(class libhttppp::Connection *)
als virtuelle Funktion, lieferst aber keine Definition (Implementation) dazu.Falls du vor hast diese Funktion jeweils nur in den abgeleiteten Klasse zu definieren, dann musst du die Funktion als pure virtual deklarieren.
Das geht so (aus
event.hpp
) - beachte das = 0:namespace libhttppp { class Queue : public ConnectionPool { public: Queue(ServerSocket *serversocket); virtual ~Queue(); virtual void RequestEvent(Connection *curcon) = 0; private: HTTPException _httpexception; }; }
Natürlich kannst du, sofern das sinnvoll ist, auch eine Default-Implementierung bereitstellen (entweder gleich im Header oder in
event.cpp
).BTW: Die Datei
event.hpp
sollte wohlqueue.hpp
heissen.Wenn du die Bibliothek als DLL benutzen möchtest, musst du noch die entsprechenden Symbole exportieren. Dazu gibt es mehrere Möglichkeiten, hier ein Dokument von MS: https://msdn.microsoft.com/en-us/library/z4zxe9k8.aspx
-
hat jetzt funktioniert danke leider bekomme ich dann neue build errors
#include "exception.h" #include "socket.h" #include "connections.h" #ifndef QUEUE_H #define QUEUE_H namespace libhttppp { class Queue : public ConnectionPool { public: Queue(ServerSocket *serversocket); virtual ~Queue(); #ifdef MSVC __declspec(dllexport) virtual void RequestEvent(Connection *curcon)=0; #else virtual void RequestEvent(Connection *curcon)=0; #endif private: HTTPException _httpexception; }; } #endif
-
habe den aufbau nochmal genauer definiert das ganze funktioniert unter gcc und clang aber leider nicht unter visualstudio es muss doch eine möglichkeit geben so etwas zu implementieren. Bin auch offen für andere vorschläge mit static habe ich es auch schon versucht ohne erfolg. Brauche einfach nur die möglichkeit eine funktion ausserhalb der klasse zu definieren um sie dann innerhalb der klasse aufzurufen.
definition der Funktion innerhalb der library
#ifndef QUEUE_H #define QUEUE_H namespace libhttppp { class Queue : public ConnectionPool { public: Queue(ServerSocket *serversocket); virtual ~Queue(); #ifdef MSVC __declspec(dllexport) virtual void RequestEvent(Connection *curcon); #else virtual void RequestEvent(Connection *curcon); #endif private: HTTPException _httpexception; }; } #endif
Aufruf der Funktion innerhalb der library
Queue::Queue(ServerSocket *socket) : ConnectionPool(socket) { HANDLE iocp = CreateIoCompletionPort(INVALID_HANDLE_VALUE, 0, 0, 0); // equals epoll_create CreateIoCompletionPort(socket, iocp, 0, 0); // equals epoll_ctl(EPOLL_CTL_ADD) for(;;){ // if(GetQueuedCompletionStatus(iocp, &number_bytes, &key, &o, INFINITE)) // equals epoll_wait() // do_something(); Connection *curcon; RequestEvent(curcon); } }
ausserhalb der library
void libhttppp::Queue::RequestEvent(libhttppp::Connection *curcon){ try{ std::cerr << "Parse Request\n"; libhttppp::HttpRequest curreq; curreq.parse(curcon); std::cerr << "Send answer\n"; sendResponse(curcon,&curreq); }catch(HTTPException &e){ std::cerr << e.what() << "\n"; throw e; } }
-
Was heisst "funktioniert nicht"? Bitte Fehlermeldungen zeigen, erwartetes/tatsächliches Verahlten beschreiben, etc.
Was heisst "so etwas zu implementieren"? Was möchtest du implementieren? Auch unter VS geht ziemlich alles was mit anderen Compilern auch geht.
Tuxist schrieb:
Aufruf der Funktion innerhalb der library ...
ausserhalb der library ...Welche Funktion meinst du?
-
RequestEvent(Connection *curcon) welche ich nicht pure virtual setzten kann da Sie innerhalb der klasse definiert und aufgerufen wird so wie außerhalb der klasse implementiert wird. Am einfachsten den Code von github ziehen und im ordner test nach der Implantation schauen. Die statische lib baut er auch aber bei der dll streikt er.
-
Alles klar, danke.
-
Habe mich in den msdn Form schlau gemacht so wie ich es vor hatte kann es der msvc nicht. Habe andere Möglichkeit aufgezeigt bekommen und implementiert.