2013-10-11 18 views
0

我已经四处搜寻试图解决这个错误的帖子,但在任何情况下,我已经在做他们建议的。无法解析的外部符号公开__thiscall只在调试模式下

我的编译输出:

main.obj:-1: error: LNK2019: unresolved external symbol "public: __thiscall KeyLogger::~KeyLogger(void)" ([email protected]@[email protected]) referenced in function _main

main.obj:-1: error: LNK2019: unresolved external symbol "public: __thiscall KeyLogger::KeyLogger(void)" ([email protected]@[email protected]) referenced in function _main

debug\AccipioKeyDemo.exe:-1: error: LNK1120: 2 unresolved externals

我知道,这是说,我已经定义了键盘记录器的构造函数和析构函数,但尚未实现,但实际上我拥有一切实现。

的main.cpp

#include <QCoreApplication> 
#include "keylogger.h" 

int main(int argc, char *argv[]) { 
    QCoreApplication a(argc, argv); 

    KeyLogger k; 

    return a.exec(); 
} 

keylogger.h

#ifndef KEYLOGGER_H 
#define KEYLOGGER_H 

#include <Windows.h> 

class KeyLogger { 

public: 
    KeyLogger(); 
    ~KeyLogger(); 

    void start(); 
    void stop(); 

private: 
    HHOOK hook; 

    LRESULT CALLBACK intercept(int code, WPARAM wparam, LPARAM lparam); 
}; 

#endif // KEYLOGGER_H 

keylogger.cpp

#include "keylogger.h" 
#include <QDebug> 

KeyLogger::KeyLogger() : hook(NULL) { 
    hook = SetWindowsHookEx(WH_KEYBOARD_LL, intercept, NULL,0); 

    if (hook == NULL) { 
     qDebug() << "HOOK FAILED"; 
    } else { 
     qDebug() << "HOOK SUCCESS"; 
    } 
} 

KeyLogger::~KeyLogger() { 

} 

void KeyLogger::start() { 
    qDebug() << "start"; 
} 

void KeyLogger::stop() { 
    qDebug() << "stop"; 
} 

LRESULT CALLBACK KeyLogger::intercept(int code, WPARAM wparam, LPARAM lparam) { 
    qDebug() << "Key Pressed"; 
    return CallNextHookEx(hook, code, wparam, lparam); 
} 

QT Pro的配置

#------------------------------------------------- 
# 
# Project created by QtCreator 2013-10-10T19:58:51 
# 
#------------------------------------------------- 

QT  += core 

QT  -= gui 

TARGET = AccipioKeyDemo 
CONFIG += console 
CONFIG -= app_bundle 

LIBS += user32.lib 

TEMPLATE = app 

SOURCES += main.cpp \ 
    keylogger.cpp 

HEADERS += \ 
    keylogger.h 
+0

为什么你需要在KeyLogger.h中包含'#include '? – billz

+0

,因为HHOOK宏是在Windows.h中定义的 – arnm

+0

您对错误理解的指示是正确的。你需要发布更多关于你的构建环境的细节。你在使用make吗? qmake的?视觉工作室?发布项目文件! –

回答

2

您的代码已损坏,因为回调方法必须是static成员 - 实质上它们必须是自由函数。由于没有办法将指针传递给拦截回调函数,所以您的挂钩必须是类成员,而不是实例成员。用互斥体保护钩子也许并不坏,以免后来忘记了自己并试图在多个线程中实例化KeyLogger

这也是一个错误,在你的情况下,KeyLogger对象是可复制的。对不打算复制的类使用Q_DISABLE_COPY宏。

您可能希望删除构建目录并重新构建项目,但请记住修复如下所示的错误,否则它将无法工作。

下面的最小化版本(只是一个main.cpp文件)工作和编译就好了。它演示了如何正确处理来自事件队列的转储数据:您必须在持有互斥锁的同时将一小部分数据从队列中复制出来,然后释放该互斥锁,然后才将其转储到其他位置。

#include <QCoreApplication> 
#include <QMutex> 
#include <QDebug> 
#include <QQueue> 
#include <QDataStream> 
#include <windows.h> 

struct KeyLoggerEvent { 
    WPARAM event; 
    KBDLLHOOKSTRUCT key; 
    KeyLoggerEvent(WPARAM ev, KBDLLHOOKSTRUCT k) : event(ev), key(k) {} 
}; 
QDataStream & operator<<(QDataStream & s, const KeyLoggerEvent & kev) { 
    s << kev.event 
    << (quint32)kev.key.flags << (quint32)kev.key.scanCode 
    << (quint32)kev.key.time << (quint32)kev.key.vkCode; 
    return s; 
} 

class KeyLogger { 
    Q_DISABLE_COPY(KeyLogger) 
    static QMutex m_hookMutex; 
    static HHOOK m_hook; 
    static QQueue<KeyLoggerEvent> m_events; 
    static LRESULT CALLBACK intercept(int code, WPARAM wparam, LPARAM lparam); 
public: 
    KeyLogger() { 
     QMutexLocker lock(&m_hookMutex); 
     Q_ASSERT(!m_hook); 
     m_hook = SetWindowsHookEx(WH_KEYBOARD_LL, intercept, NULL,0); 
     if (!m_hook) qDebug() << "HOOK FAILED"; 
     lock.unlock(); 
    } 
    ~KeyLogger() { 
     QMutexLocker lock(&m_hookMutex); 
     if (m_hook) UnhookWindowsHookEx(m_hook); 
     m_hook = NULL; 
    } 
    //! Dumps a bunch of events to the stream. Returns false if no more events remain in the 
    //! log. To avoid lock contention, it keeps the queue lock for a very short amount of time. 
    bool dump(QDataStream & s) { 
     int batchCount = 1000; 
     QQueue<KeyLoggerEvent> dumpQueue; 
     QMutexLocker lock(&m_hookMutex); 
     while (batchCount-- && !m_events.empty()) { 
     dumpQueue.enqueue(m_events.dequeue()); 
     } 
     bool more = !m_events.empty(); 
     lock.unlock(); 
     // The below could block for a long time, thus it works from a local copy. 
     while (! dumpQueue.empty()) s << dumpQueue.dequeue(); 
     return more; 
    } 
}; 

QMutex KeyLogger::m_hookMutex; 
HHOOK KeyLogger::m_hook = NULL; 
QQueue<KeyLoggerEvent> KeyLogger::m_events; 

LRESULT CALLBACK KeyLogger::intercept(int code, WPARAM wparam, LPARAM lparam) { 
    qDebug() << "Key Event"; 
    QMutexLocker lock(&m_hookMutex); 
    if (code >= 0) { 
     KBDLLHOOKSTRUCT * key = reinterpret_cast<KBDLLHOOKSTRUCT*>(lparam); 
     m_events.enqueue(KeyLoggerEvent(wparam, *key)); 
    } 
    HHOOK hook = KeyLogger::m_hook; 
    lock.unlock(); 
    return CallNextHookEx(hook, code, wparam, lparam); 
} 

int main(int argc, char *argv[]) 
{ 
    QCoreApplication a(argc, argv); 
    KeyLogger k; 
    return a.exec(); 
} 
0

您会收到链接错误,其中链接程序找不到具有构造函数和析构函数的obj文件。这意味着keylogger.cpp不是编译的,或者链接器找不到它的obj文件。检查您的项目的设置。

+0

所有的文件被添加到项目中,我的配置已被添加到问题 – arnm

+0

所以显然我只在调试模式下编译时出现此错误 – arnm

相关问题