与应用程序链接错误[关闭]
Posted
技术标签:
【中文标题】与应用程序链接错误[关闭]【英文标题】:Link Error with application [closed] 【发布时间】:2013-12-27 08:12:14 【问题描述】:我在构建后出现此链接错误,但不知道出处。我检查了链接器属性中的所有外部依赖项,但没有。为您提供标题和 cpp 的正文:
文件 mainwindow.h
#ifndef MAINWINDOW_H
#define MAINWINDOW_H
#include <QMainWindow>
#include <activemq/library/ActiveMQCPP.h>
#include <decaf/lang/Thread.h>
#include <decaf/lang/Runnable.h>
#include <decaf/util/concurrent/CountDownLatch.h>
#include <decaf/lang/Integer.h>
#include <decaf/lang/Long.h>
#include <decaf/lang/System.h>
#include <activemq/core/ActiveMQConnectionFactory.h>
#include <activemq/util/Config.h>
#include <cms/Connection.h>
#include <cms/Session.h>
#include <cms/TextMessage.h>
#include <cms/BytesMessage.h>
#include <cms/MapMessage.h>
#include <cms/ExceptionListener.h>
#include <cms/MessageListener.h>
#include <include/IfacomAmqSender.h>
#include <include/IfacomAmqReceiver.h>
using namespace activemq::core;
using namespace decaf::util::concurrent;
using namespace decaf::util;
using namespace decaf::lang;
using namespace cms;
namespace Ui
class MainWindow;
class MainWindow : public QMainWindow
Q_OBJECT
public:
explicit MainWindow(QWidget *parent = 0);
~MainWindow();
void onMessage(const Message*);
void connectionSender();
private slots:
void on_pushButton_clicked();
void on_pushButton_2_clicked();
private:
Ui::MainWindow *ui;
;
#endif // MAINWINDOW_H
文件 mainwindow.cpp
#include "include/IfacomAmqSender.h"
#include "include/IfacomAmqReceiver.h"
#include "mainwindow.h"
#include "ui_mainwindow.h"
#include <activemq/library/ActiveMQCPP.h>
#include <decaf/lang/Thread.h>
#include <decaf/lang/Runnable.h>
#include <decaf/util/concurrent/CountDownLatch.h>
#include <decaf/lang/Integer.h>
#include <decaf/lang/Long.h>
#include <decaf/lang/System.h>
#include <activemq/core/ActiveMQConnectionFactory.h>
#include <activemq/util/Config.h>
#include <cms/Connection.h>
#include <cms/Session.h>
#include <cms/TextMessage.h>
#include <cms/BytesMessage.h>
#include <cms/MapMessage.h>
#include <cms/ExceptionListener.h>
#include <cms/MessageListener.h>
#include <stdlib.h>
#include <stdio.h>
#include <iostream>
MainWindow::MainWindow(QWidget *parent) :
QMainWindow(parent),
ui(new Ui::MainWindow)
ui->setupUi(this);
MainWindow::~MainWindow()
delete ui;
/*********** Definition m_IfacomMessageBroker ******************/
std::string brokerURI = "failover://(tcp://localhost:61613?wireFormat=stomp)"; // localhost;
// brokerURI = "failover://(tcp://localhost:61616)"; // localhost
// Queue name
std::string destName = "IFACOM-CMS";
// Queue or Topic
bool useTopics = false; // true=Topic, false=Queue
// SESSION_TRANSACTED or AUTO_ACKNOWLEDGE
bool sessionTransacted = false; // if true, commit all messages
// Message parametres
int numMess=1; int waitMillis=1000;
// Definition of object m_IfacomMessageBroker
//IfacomAmqSender m_IfacomMessageBroker(brokerURI,numMess, useTopics, sessionTransacted, destName,waitMillis);
IfacomAmqSender* m_IfacomMessageBroker = new IfacomAmqSender(brokerURI,numMess, useTopics, sessionTransacted, destName,waitMillis);
void MainWindow::connectionSender()
activemq::library::ActiveMQCPP::initializeLibrary();
// ***** Initialisation **************************************************************
//m_IfacomMessageBroker.initConnection();
m_IfacomMessageBroker->initConnection();
m_IfacomMessageBroker->getSession()->createTextMessage();
//IfacomAmqReceiver IfacomAmqReceiverBroker(brokerURI,10, useTopics, sessionTransacted, destName,2000);
//IfacomAmqReceiverBroker.initConnection();
//IfacomAmqReceiverBroker.getConsumer()->setMessageListener(this);
void MainWindow::on_pushButton_clicked()
connectionSender();
void MainWindow::on_pushButton_2_clicked()
文件 main.cpp
#include "mainwindow.h"
#include <include\IfacomAmqSender.h>
#include <include\IfacomAmqReceiver.h>
#include <QApplication>
int main(int argc, char *argv[])
QApplication prog(argc, argv);
MainWindow w;
w.show();
return prog.exec();
以及链接错误中调用的文件 IfacomAmqSender.h:
#ifndef _IfacomAmqSender_h
#define _IfacomAmqSender_h
#include <activemq/library/ActiveMQCPP.h>
#include <decaf/lang/Thread.h>
#include <decaf/lang/Runnable.h>
#include <decaf/util/concurrent/CountDownLatch.h>
#include <decaf/lang/Integer.h>
#include <decaf/lang/Long.h>
#include <decaf/lang/System.h>
#include <activemq/core/ActiveMQConnectionFactory.h>
#include <activemq/util/Config.h>
#include <cms/Connection.h>
#include <cms/Session.h>
#include <cms/TextMessage.h>
#include <cms/BytesMessage.h>
#include <cms/MapMessage.h>
#include <cms/ExceptionListener.h>
#include <cms/MessageListener.h>
#include <stdlib.h>
#include <stdio.h>
#include <iostream>
#include <memory>
using namespace activemq::core;
using namespace decaf::util::concurrent;
using namespace decaf::util;
using namespace decaf::lang;
using namespace cms;
class IfacomAmqSender : public ExceptionListener
private:
CountDownLatch m_latch;
CountDownLatch m_doneLatch;
Connection* m_connection;
Session* m_session;
Destination* m_destination;
MessageConsumer* m_consumer;
MessageProducer* m_producer;
std::auto_ptr<TextMessage> m_message;
long m_waitMillis;
bool m_useTopic;
bool m_sessionTransacted;
std::string m_brokerURI;
std::string m_destName;
DeliveryMode m_message_delivery_mode;
int m_message_priority;
IfacomAmqSender(const IfacomAmqSender&);
IfacomAmqSender& operator=(const IfacomAmqSender&);
public:
IfacomAmqSender (const std::string&, int, bool,bool,const std::string&,int);
//explicit IfacomAmqSender(const std::string&, int, bool, bool, const std::string&, int);
//IfacomAmqSender(const std::string&, bool, bool, const std::string&);
~IfacomAmqSender();
void close();
void waitUntilReady();
void cleanup();
// KH
void createConnection();
void createSession();
void createDestination();
void createProducer();
void initConnection();
virtual void sendMessage(std::string);
// Send a ActiveMQ Message
virtual void sendMessage(std::auto_ptr<TextMessage>);
//--------------------------------------------------
// If something bad happens you see it here as this class is also been
// registered as an ExceptionListener with the connection.
virtual void onException(const CMSException&) ;
// Message Priority (0:Lowest - 9:Highest)
void setPriority(int);
int getPriority();
// Message Delivery Mode
void setDeliveryMode(DeliveryMode);
DeliveryMode getDeliveryMode();
Session* getSession();
;
#endif
文件 IfacomAmqSender.cpp:
#include <activemq/library/ActiveMQCPP.h>
#include <decaf/lang/Thread.h>
#include <decaf/lang/Runnable.h>
#include <decaf/util/concurrent/CountDownLatch.h>
#include <decaf/lang/Integer.h>
#include <decaf/lang/Long.h>
#include <decaf/lang/System.h>
#include <activemq/core/ActiveMQConnectionFactory.h>
#include <activemq/util/Config.h>
#include <cms/Connection.h>
#include <cms/Session.h>
#include <cms/TextMessage.h>
#include <cms/BytesMessage.h>
#include <cms/MapMessage.h>
#include <cms/ExceptionListener.h>
#include <cms/MessageListener.h>
#include <stdlib.h>
#include <stdio.h>
#include <iostream>
#include <memory>
#include "IfacomAmqSender.h"
using namespace activemq::core;
using namespace decaf::util::concurrent;
using namespace decaf::util;
using namespace decaf::lang;
using namespace cms;
using namespace std;
IfacomAmqSender::IfacomAmqSender(const std::string& brokerURI, int numMessages, bool useTopic = false, bool sessionTransacted = false, const std::string& destName = "IFACOM-CMS", int waitMillis = 1000) :
m_latch(1),
m_doneLatch(numMessages),
m_connection(NULL),
m_session(NULL),
m_destination(NULL),
m_consumer(NULL),
m_waitMillis(waitMillis),
m_useTopic(useTopic),
m_sessionTransacted(sessionTransacted),
m_destName(destName),
m_brokerURI(brokerURI)
/*IfacomAmqSender::IfacomAmqSender(const std::string& brokerURI, bool useTopic = false, bool sessionTransacted = false, const std::string& destName = "IFACOM-CMS") :
m_latch(1),
m_doneLatch(1),
m_connection(NULL),
m_session(NULL),
m_destination(NULL),
m_consumer(NULL),
m_waitMillis(1000),
m_useTopic(useTopic),
m_sessionTransacted(sessionTransacted),
m_destName(destName),
m_brokerURI(brokerURI)
*/
IfacomAmqSender::~IfacomAmqSender()
cleanup();
void IfacomAmqSender::close()
this->cleanup();
void IfacomAmqSender::waitUntilReady()
m_latch.await();
//------ Init connexion ---------------
void IfacomAmqSender::createConnection()
// Create a ConnectionFactory
auto_ptr<ConnectionFactory> connectionFactory(ConnectionFactory::createCMSConnectionFactory(m_brokerURI));
// Create a Connection
m_connection = connectionFactory->createConnection();
m_connection->start();
m_connection->setExceptionListener(this);
void IfacomAmqSender::createSession()
// Create a Session
if (this->m_sessionTransacted == true)
m_session = m_connection->createSession(Session::SESSION_TRANSACTED);
else
m_session = m_connection->createSession(Session::AUTO_ACKNOWLEDGE);
void IfacomAmqSender::createDestination()
// Create the destination (Topic or Queue)
if (m_useTopic)
m_destination = m_session->createTopic(m_destName);
else
m_destination = m_session->createQueue(m_destName);
void IfacomAmqSender::createProducer()
m_producer = m_session->createProducer(m_destination);
m_producer->setDeliveryMode(DeliveryMode::NON_PERSISTENT);
void IfacomAmqSender::initConnection()
try
createConnection();
// Create the session
createSession();
// Create the destination (Topic or Queue)
createDestination();
// Create a MessageProducer from the Session to the Topic or Queue
createProducer();
m_producer->setDeliveryMode(DeliveryMode::NON_PERSISTENT);
// Indicate we are ready for messages.
m_latch.countDown();
// Wait while asynchronous messages come in.
m_doneLatch.await(m_waitMillis);
catch (CMSException& e)
// Indicate we are ready for messages.
//latch.countDown();
e.printStackTrace();
void IfacomAmqSender::sendMessage(string text)
try
std::auto_ptr<TextMessage> message(m_session->createTextMessage(text));
// to set a property
////message->setIntProperty("Integer", ix);
m_producer->send(message.get());
message->setCMSTimestamp(System::currentTimeMillis());
catch (CMSException& e)
e.printStackTrace();
// Send a ActiveMQ Message
void IfacomAmqSender::sendMessage(std::auto_ptr<TextMessage> amq_message)
try
amq_message->setCMSTimestamp(System::currentTimeMillis());
m_producer->send(amq_message.get());
catch (CMSException& e)
e.printStackTrace();
//--------------------------------------------------
// If something bad happens you see it here as this class is also been
// registered as an ExceptionListener with the connection.
void IfacomAmqSender::onException(const CMSException& ex AMQCPP_UNUSED)
printf("CMS Exception occurred. Shutting down client.\n");
ex.printStackTrace();
exit(1);
// Message Priority (0:Lowest - 9:Highest)
void IfacomAmqSender::setPriority(int priority)m_message_priority = priority;
int IfacomAmqSender::getPriority()return m_message_priority;
// Message Delivery Mode
void IfacomAmqSender::setDeliveryMode(DeliveryMode delivery_mode)m_message_delivery_mode = delivery_mode;
DeliveryMode IfacomAmqSender::getDeliveryMode()return m_message_delivery_mode;
Session* IfacomAmqSender::getSession()
return m_session;
void IfacomAmqSender::cleanup()
if (m_connection != NULL)
try
m_connection->close();
catch (cms::CMSException& ex)
ex.printStackTrace();
// Destroy resources.
try
delete m_destination;
m_destination = NULL;
delete m_consumer;
m_consumer = NULL;
delete m_session;
m_session = NULL;
delete m_connection;
m_connection = NULL;
catch (CMSException& e)
e.printStackTrace();
错误是:
Error 2 error LNK2019: unresolved external symbol "public: __thiscall IfacomAmqSender::IfacomAmqSender(class std::basic_string<char,struct std::char_traits<char>,class std::allocator<char> > const &,int,bool,bool,class std::basic_string<char,struct std::char_traits<char>,class std::allocator<char> > const &,int)" (??0IfacomAmqSender@@QAE@ABV?$basic_string@DU?$char_traits@D@std@@V?$allocator@D@2@@std@@H_N10H@Z) referenced in function "void __cdecl `dynamic initializer for 'm_IfacomMessageBroker''(void)" (??__Em_IfacomMessageBroker@@YAXXZ) C:\Users\Marco\Desktop\Activemq\ReleaseVersions\GUI-CMS-SENDER\mainwindow.obj GUI-CMS-SENDER
Error 3 error LNK2019: unresolved external symbol "public: void __thiscall IfacomAmqSender::initConnection(void)" (?initConnection@IfacomAmqSender@@QAEXXZ) referenced in function "public: void __thiscall MainWindow::connectionSender(void)" (?connectionSender@MainWindow@@QAEXXZ) C:\Users\Marco\Desktop\Activemq\ReleaseVersions\GUI-CMS-SENDER\mainwindow.obj GUI-CMS-SENDER
Error 4 error LNK2019: unresolved external symbol "public: class cms::Session * __thiscall IfacomAmqSender::getSession(void)" (?getSession@IfacomAmqSender@@QAEPAVSession@cms@@XZ) referenced in function "public: void __thiscall MainWindow::connectionSender(void)" (?connectionSender@MainWindow@@QAEXXZ) C:\Users\Marco\Desktop\Activemq\ReleaseVersions\GUI-CMS-SENDER\mainwindow.obj GUI-CMS-SENDER
命令行是:
/OUT:"debug\\GUI-CMS-SENDER.exe" /MANIFEST /NXCOMPAT /PDB:"debug\GUI-CMS-SENDER.pdb" /DYNAMICBASE "qtmaind.lib" "C:\Qt\Qt5.1.1\5.1.1\msvc2012\\lib\Qt5Widgetsd.lib" "C:\Qt\Qt5.1.1\5.1.1\msvc2012\\lib\Qt5Guid.lib" "C:\Qt\Qt5.1.1\5.1.1\msvc2012\\lib\Qt5Cored.lib" "libEGLd.lib" "libGLESv2d.lib" "gdi32.lib" "user32.lib" "Qt5Cored.lib" "Qt5Guid.lib" "libapr-1.lib" "libactivemq-cppd.lib" "ws2_32.lib" "kernel32.lib" "winspool.lib" "comdlg32.lib" "advapi32.lib" "shell32.lib" "ole32.lib" "oleaut32.lib" "uuid.lib" "odbc32.lib" "odbccp32.lib" /DEBUG /MACHINE:X86 /SAFESEH /PGD:"debug\GUI-CMS-SENDER.pgd" /SUBSYSTEM:WINDOWS /MANIFESTUAC:"level='asInvoker' uiAccess='false'" /ManifestFile:"Win32\Debug\GUI-CMS-SENDER.exe.intermediate.manifest" /ERRORREPORT:PROMPT /NOLOGO /LIBPATH:"lib" /LIBPATH:"C:\Qt\Qt5.1.1\5.1.1\msvc2012\\lib" /LIBPATH:"\lib" /LIBPATH:"C:\Users\Marco\Desktop\Activemq\ReleaseVersions\GUI-CMS-SENDER\include" /TLBID:1
【问题讨论】:
你是否在某处从IfacomAmqSender.h
定义了这些函数?
是的,我在 IfacomAmqSender.cpp 文件中定义了所有函数...你也需要这个文件的代码吗?
你的链接器命令行是什么?
旁注:每个文件中都有大量的标头#included。将它们削减到每个文件所需的最小值。如果您在尝试找出链接器问题时这样做,请不要打扰;标头很少对链接器行为产生任何影响。
旁注 2:不要在头文件中使用 using namespace
声明。这会污染每个包含有问题的标头的文件。
【参考方案1】:
根据最近添加的链接器行,实际上您似乎没有链接到库。您需要将其放入应用程序的 qmake 项目文件中:
LIBS += -L/path/to/your/library -lyourlibrary
如果这不起作用,请确保您尝试链接的库版本包含必要的符号。我通常在 Linux 上使用“nm -a”或“objdump”,但在 Windows 上也必须有一些等效版本。
编辑:由于您似乎使用 Visual Studio 而不是 qmake
,因此您需要确保解决方案文件中有两件事:
1) 构建的库具有符号。为此,您需要有可用的符号,因此请确保它们已内置到库中。您应该将所有必要的文件添加到项目中,但最重要的是源文件 (cpp)。
2) 您需要确保在针对库构建应用程序时,您已根据库路径和名称正确设置了 Visual Studio。这个设置可以通过UI设置选项来完成。
这里有一些截图用于说明:
【讨论】:
是的 Laszlo...但是我在 Visual Studio 中打开了项目文件,即我使用加载项导入了 .pro 文件,所以我认为如果我将库包含在 . pro文件... @CecchinoSMI:好的,你还没有提到Visual Studio,但是如果你不使用qmake项目文件,你需要像往常一样在Visual Studio项目选项中设置库链接,但是解决方案,不是吗? 是的,当然@Laszlo,我有 Visual Studio 解决方案文件,并且我在链接器选项中设置了我需要的所有库,如果你愿意,我可以向你展示我添加的库依赖项。 .. @CecchinoSMI:请这样做。 这些是附加库目录【参考方案2】:当您忘记将源文件包含到项目中时,通常会出现此类问题。
如果您使用的是 qmake .pro
项目文件,请确保您已将 IfacomAmqSender.cpp
包含在其中(如 @loentar 指出的那样):
SOURCES += (previous source files) \
IfacomAmqSender.cpp
如果您不使用 qmake,或者只需将 IfacomAmqSender.cpp
添加到 Visual Studio 项目(项目 - 添加现有项...或在解决方案资源管理器中右键单击 - 添加 - 现有项...)。
然后一切都应该编译和链接好。
【讨论】:
上面提到的错误,显示在Visual Studio中......所以如果我在.pro文件中添加或不添加这些文件是无关紧要的。我在链接器属性中添加库目录....但错误没有解决... 另外,这还不够,因为您确实需要设置库路径和库。 @LaszloPapp 是的,您需要为外部库 (.lib
) 指定库路径和库。但是IfacomAmqSender
是在IfacomAmqSender.cpp
文件中实现的,所以不需要特定的.lib
库。
OP 希望有一个外部库。请看评论讨论。因此,这不是一个正确的答案。我会删除它,但我会把它留给你。
向下滚动IfacomAmqSender.cpp
,这是实现文件。如果 OP 希望有一个外部库,他需要单独编译它。以上是关于与应用程序链接错误[关闭]的主要内容,如果未能解决你的问题,请参考以下文章