I'm encountering the following linker issue when I try to build my project.
I've had a look through the other posts here and as far as I can see, the only externals I'm using are members of standard (and identified with std::), or primitives. Is there something obvious that I'm missing here?
Building using Eclipse C++ (Mars) on Win 7 professional 64bit using the internal eclipse builder.
Log:
link /debug /nologo /OUT:SAD-Snoop.exe "src\ByteScanner.obj" "src\EncType.obj" "src\SAD-Snoop.obj" "src\SearchHits.obj"
SearchHits.obj : error LNK2019: unresolved external symbol "public: long __thiscall SearchHits::GetHitAddress(unsigned int)" (GetHitAddress#SearchHits##QAEJI#Z) referenced in function "public: bool __thiscall SearchHits::Merge(class SearchHits)" (?Merge#SearchHits##QAE_NV1##Z)
SAD-Snoop.exe : fatal error LNK1120: 1 unresolved externals
14:28:44 Build Finished (took 909ms)
Header:
/*
* SearchHits.h
*
* Created on: 30 Jun 2015
* Author: Nick Boyd
*/
#ifndef SEARCHHITS_H_
#define SEARCHHITS_H_
#include <iostream>
#include <string>
#include <vector>
class SearchHits {
public:
SearchHits();
~SearchHits();
bool AddHit(std::string content, long address);
unsigned int CountHits();
std::string GetHit(unsigned int hitNumber);
long GetHitAddress(unsigned int hitNumber);
bool Merge(SearchHits hits);
private:
std::vector<std::string> hits;
std::vector<long> hitAddresses;
};
#endif /* SEARCHHITS_H_ */
class:
/*
* SearchHits.cpp
*
* Created on: 30 Jun 2015
* Author: Nick Boyd
*/
#include "SearchHits.h"
#include <string>
#include <iostream>
#include <vector>
std::vector<std::string> hitContents;
std::vector<long> hitAddresses;
SearchHits::SearchHits() {
}
SearchHits::~SearchHits() {
hitContents.clear();
hitAddresses.clear();
}
bool SearchHits::AddHit(std::string hitContent, long address) {
hitContents.push_back(hitContent);
hitAddresses.push_back(address);
return ((hitContents.back() == hitContent)
&& (hitAddresses.back() == address));
}
unsigned int SearchHits::CountHits() {
return hitContents.size();
}
std::string SearchHits::GetHit(unsigned int hitNumber) {
if (hitNumber < hitContents.size()) {
return hitContents[hitNumber];
} else {
std::cout << "Error in Function [SearchHits::GetHit()]" << std::endl
<< "Parameter [hitNumber] out of bounds: "
<< hitNumber + " Upper Limit: " << hitContents.size()
<< std::endl;
throw new std::invalid_argument(
"Error in Function [SearchHits::GetHit()] Parameter [hitNumber] out of bounds: "
+ std::to_string(hitNumber));
}
}
long GetHitAddress(unsigned int hitNumber) {
if (hitNumber < hitContents.size()) {
return hitAddresses[hitNumber];
} else {
std::cout << "Error in Function [SearchHits::GetHitAddress()]"
<< std::endl << "Parameter [hitNumber] out of bounds: "
<< hitNumber << " Upper Limit: " << hitContents.size()
<< std::endl;
throw new std::invalid_argument(
"Error in Function [SearchHits::GetHitAddress()] Parameter [hitNumber] out of bounds: "
+ std::to_string(hitNumber));
}
}
bool SearchHits::Merge(SearchHits hits) {
bool overallResult = true;
unsigned int i = 0;
while ((i < hits.CountHits()) && overallResult) {
bool tempResult = false;
unsigned char attemptNum = 1;
while ((tempResult == false) && (attemptNum++ <= 5)) {
tempResult = this->AddHit(hits.GetHit(i),hits.GetHitAddress(i));
}
overallResult = (overallResult && tempResult);
++i;
}
if (overallResult) {
hits.~SearchHits();
}
return overallResult;
}
Change
long GetHitAddress(unsigned int hitNumber)
to
long SearchHits::GetHitAddress(unsigned int hitNumber)
Related
This question already has answers here:
c++ multiple definitions of a variable
(5 answers)
multiple definition error c++
(2 answers)
What exactly is One Definition Rule in C++?
(1 answer)
Closed 2 years ago.
I am attempting to compile my c++ code, and I continue getting the error:
/tmp/ccEsZppG.o:(.bss+0x0): multiple definition of `mailboxes'
/tmp/ccEZq43v.o:(.bss+0x0): first defined here
/tmp/ccEsZppG.o:(.bss+0xc0): multiple definition of `threads'
/tmp/ccEZq43v.o:(.bss+0xc0): first defined here
/tmp/ccEsZppG.o:(.bss+0x120): multiple definition of `semaphores'
/tmp/ccEZq43v.o:(.bss+0x120): first defined here
collect2: error: ld returned 1 exit status
Here is my code:
addem.cpp
#include <stdio.h>
#include <iostream>
#include <stdlib.h>
#include <semaphore.h>
#include <pthread.h>
#include "mailbox.h"
using namespace std;
void *sumUp(void *arg);
int main(int argc, char *argv[]) {
int numThreads, minThreads, maxInt, minInt;
if (argc < 3) {
cout << "Error: Need three arguments" << endl;
return 1;
}
numThreads = atoi(argv[1]);
maxInt = atoi(argv[2]);
minThreads = 1;
minInt = 1;
if (numThreads < 1) {
cout << "Cannot work with less than one thread\n"
<< "It's okay but do better next time!\n"
<< "We'll work with 1 thread this time.\n";
numThreads = minThreads;
} else if (numThreads > MAXTHREAD) {
cout << "Sorry, the max for threads is 10.\n"
<< "We'll work with 10 threads this time.\n";
numThreads = MAXTHREAD;
}
if (maxInt < 1) {
cout << "What do you want me to do? I can't count backwards!\n"
<< "I can barely count forwards! Let's make the max number\n"
<< "be 1 to save time\n";
maxInt = minInt;
}
struct msg outgoingMail[numThreads];
int divider = maxInt / numThreads;
int count = 1;
//initialize arrays (mailboxes, semaphores)
for (int i = 0; i < numThreads; i++) {
sem_init(&semaphores[i], 0, 1);
outgoingMail[i].iSender = 0;
outgoingMail[i].type = RANGE;
outgoingMail[i].value1 = count;
count = count + divider;
if (i = numThreads - 1) {
outgoingMail[i].value2 = maxInt;
} else {
outgoingMail[i].value2 = count;
}
}
for (int message = 0; message < numThreads; message++) {
SendMsg(message+1, outgoingMail[message]);
}
int thread;
for (thread = 0; thread <= numThreads; thread++) {
pthread_create(&threads[thread], NULL, &sumUp, (void *)(intptr_t)(thread+1));
}
struct msg incomingMsg;
int total = 0;
for (thread = 0; thread < numThreads; thread++) {
RecvMsg(0, incomingMsg);
total = total + incomingMsg.value1;
}
cout << "The total for 1 to " << maxInt << " using "
<< numThreads << " threads is " << total << endl;
return 0;
}
void *sumUp(void *arg) {
int index,total;
index = (intptr_t)arg;
struct msg message;
RecvMsg(index, message);
message.iSender = index;
message.type = ALLDONE;
total = 0;
for (int i = message.value1; i <= message.value2; i++) {
total += i;
}
SendMsg(0, message);
return (void *) 0;
}
mailbox.cpp
#include <stdio.h>
#include <iostream>
#include "mailbox.h"
using namespace std;
int SendMsg(int iTo, struct msg &Msg) {
if (safeToCall(iTo)) {
cout << "Error calling SendMsg" << endl;
return 1;
}
sem_wait(&semaphores[iTo]);
mailboxes[iTo] = Msg;
sem_post(&semaphores[iTo]);
return 0;
}
int RecvMsg(int iFrom, struct msg &Msg) {
sem_wait(&semaphores[iFrom]);
if (safeToCall(iFrom)) {
cout << "Error calling RecvMsg" << endl;
return 1;
}
mailboxes[iFrom] = Msg;
sem_post(&semaphores[iFrom]);
return 0;
}
bool safeToCall(int location) {
bool safe = !(location < 0 || location > MAXTHREAD + 1);
return safe;
//return true;
}
mailbox.h
#ifndef MAILBOX_H_
#define MAILBOX_H_
#define RANGE 1
#define ALLDONE 2
#define MAXTHREAD 10
#include <semaphore.h>
#include <pthread.h>
struct msg {
int iSender; /* sender of the message (0 .. numThreads)*/
int type; /* its type */
int value1; /* first value */
int value2; /* second value */
};
struct msg mailboxes[MAXTHREAD + 1];
pthread_t threads[MAXTHREAD + 1];
sem_t semaphores[MAXTHREAD + 1];
int SendMsg(int iTo, struct msg &Msg);
int RecvMsg(int iFrom, struct msg &Msg);
bool safeToCall(int location);
#endif
I am compiling the code with the command
g++ -o addem addem.cpp mailbox.cpp -lpthread
I have tried commenting out all of the function bodies in the source code to leave them as stub functions, and the same error occurs. The only way I have been able to compile the file is if I comment out the function bodies, and remove
#include "mailbox.h"
From at least one of the files. I feel it has to do with how I am initializing the arrays? But I cannot figure out a workaround.
I am writing mosquitto code for consuming the message after subscribing to a particular topic. Now I want to set different configuration for mosquitto like
autosave_interval 100
persistence true
persistence_location /var/lib/mosquitto/
persistence_file mosquitto.db
But I have no idea how to set this configuration in c++. I tried to google it but could not found any result. Plz, help. Below is c++ code for mosquito
myMosq.h
/*
* myMosq.h
*
* Created on: Jul 28, 2016
* Author: nilav
*/
#include <iostream>
#ifndef MYMOSQ_H_
#define MYMOSQ_H_
#include <mosquittopp.h>
#include <mosquitto.h>
using namespace std;
class myMosq : public mosqpp::mosquittopp
{
private:
const char * host;
const char * id;
const char * topic;
int port;
int keepalive;
void on_connect(int rc);
void on_message(const struct mosquitto_message *message);
void on_disconnect(int rc);
void on_subscribe(int mid, int qos_count, const int *granted_qos);
void on_publish(int mid);
void on_unsubscribe(int mid);
public:
myMosq(const char *id, const char * _topic, const char *host, int port);
~myMosq();
bool send_message(string responseMessage);
bool receive_message();
void writeToDatabase(string query);
};
#endif
myMosq.cpp
#include <cstdio>
#include <cstring>
#include <iostream>
#include "myMosq.h"
#include <mosquittopp.h>
#include "Configuration.h"
#include "Databases.h"
using namespace std;
Configuration configuration;
myMosq::myMosq(const char * _id,const char * _topic, const char * _host, int _port) : mosquittopp(_id)
{
mosqpp::lib_init(); // Mandatory initialization for mosquitto library
this->keepalive = 60; // Basic configuration setup for myMosq class
this->id = _id;
this->port = _port;
this->host = _host;
this->topic = _topic;
connect_async(host, // non blocking connection to broker request
port,
keepalive);
loop_start(); // Start thread managing connection / publish / subscribe
};
myMosq::~myMosq() {
loop_stop(); // Kill the thread
mosqpp::lib_cleanup(); // Mosquitto library cleanup
}
bool myMosq::receive_message()
{
int set = subscribe(NULL, configuration.subscriptionTopic.c_str(),2);
return set;
}
bool myMosq::send_message(string responseMessage) {
int ret = publish(NULL,configuration.producerTopic.c_str(),strlen(responseMessage.c_str()),responseMessage.c_str(),1,false);
return (ret = MOSQ_ERR_SUCCESS);
}
void myMosq::on_disconnect(int rc) {
std::cout << ">> myMosq - disconnection(" << rc << ")" << std::endl;
}
void myMosq::on_connect(int rc)
{
if ( rc == 0 ) {
std::cout << ">> myMosq - connected with server" << std::endl;
} else {
std::cout << ">> myMosq - Impossible to connect with server(" << rc << ")" << std::endl;
}
}
void myMosq::on_message(const struct mosquitto_message *message) {
char * pchar = (char*)(message->payload);
string str(pchar);
writeToDatabase(str);
}
void myMosq::on_subscribe(int mid, int qos_count, const int *granted_qos)
{
std::cout << ">> subscription succeeded (" << mid << ") " << std::endl;
}
void myMosq::on_publish(int mid) {
std::cout << ">> myMosq - Message (" << mid << ") succeed to be published " << std::endl;
}
void myMosq::writeToDatabase(string query) {
Databases* database = new Databases(configuration.db,
configuration.dbPort, configuration.username, configuration.password,
configuration.schema);
database->writeDatabase(query);
if(database->responseMessage == "") {
database->responseMessage = "SUCCESS";
}
this->send_message(database->responseMessage);
}
void myMosq::on_unsubscribe(int mid) {
cout<<"unscubscribed";
};
The options you are seeing are for mosquitto broker which acts almost like a server.
Mosquitto C++ library is a client library and those options(e.g. autosave_interval) are not valid for a client. Regarding persistance, mosquitto C/C++ client library doesn't offer file persistance currently.
This is my second attempt at a C++ program so I'm still learning.
I'm trying to create a DLL to work with Metatrader 4 which uses the ta-lib technical analysis library using Visual Studio 2013 Community.
However, when I build the solution I get the following linker errors and I don't know how to fix them.
Error 4 error LNK2005: "private: __thiscall type_info::type_info(class type_info const &)" (??0type_info##AAE#ABV0##Z) already defined in libcmt.lib(typinfo.obj) C:\Users\Documents\Visual Studio 2013\Projects\iDEMA\iDEMA\MSVCRT.lib(ti_inst.obj) iDEMA
Error 5 error LNK2005: "private: class type_info & __thiscall type_info::operator=(class type_info const &)" (??4type_info##AAEAAV0#ABV0##Z) already defined in libcmt.lib(typinfo.obj) C:\Users\Documents\Visual Studio 2013\Projects\iDEMA\iDEMA\MSVCRT.lib(ti_inst.obj) iDEMA
Error 2 error LNK2005: _free already defined in libcmt.lib(free.obj) C:\Users\Documents\Visual Studio 2013\Projects\iDEMA\iDEMA\MSVCRT.lib(MSVCR120.dll) iDEMA
Error 3 error LNK2005: _malloc already defined in libcmt.lib(malloc.obj) C:\Users\Documents\Visual Studio 2013\Projects\iDEMA\iDEMA\MSVCRT.lib(MSVCR120.dll) iDEMA
Warning 1 warning LNK4098: defaultlib 'MSVCRT' conflicts with use of other libs; use /NODEFAULTLIB:library C:\Users\Documents\Visual Studio 2013\Projects\iDEMA\iDEMA\LINK iDEMA
Error 7 error LNK1169: one or more multiply defined symbols found C:\Users\Documents\Visual Studio 2013\Projects\iDEMA\Release\iDEMA.dll iDEMA
Error 6 error LNK2005: _DllMain#12 already defined in uafxcw.lib(dllmodul.obj) C:\Users\Documents\Visual Studio 2013\Projects\iDEMA\iDEMA\* CIL library *(* CIL module *) iDEMA
My header file is this
// The following ifdef block is the standard way of creating macros which make exporting
// from a DLL simpler. All files within this DLL are compiled with the IDEMA_EXPORTS
// symbol defined on the command line. This symbol should not be defined on any project
// that uses this DLL. This way any other project whose source files include this file see
// IDEMA_API functions as being imported from a DLL, whereas this DLL sees symbols
// defined with this macro as being exported.
#ifdef IDEMA_EXPORTS
#define IDEMA_API __declspec(dllexport)
#else
#define IDEMA_API __declspec(dllimport)
#endif
#pragma pack(push,1)
struct RateInfo
{
__int64 ctm;
double open;
double low;
double high;
double close;
unsigned __int64 vol_tick;
int spread;
unsigned __int64 vol_real;
};
#pragma pack(pop)
enum ENUM_PRICE
{
PRICE_OPEN,
PRICE_LOW,
PRICE_HIGH,
PRICE_CLOSE
};
// This class is exported from the iDEMA.dll
class IDEMA_API CiDEMA {
public:
CiDEMA(void);
double iDEMA(RateInfo, int, int, int, ENUM_PRICE);
};
extern IDEMA_API int niDEMA;
IDEMA_API int fniDEMA(void);
#include <windows.h>
#include <stdlib.h>
#include <stdio.h>
#include <iostream>
#include <vector>
#include <string>
#include "C:\ta-lib-0.4.0-msvc\ta-lib\c\include\ta_libc.h"
#pragma once
#ifndef __AFXWIN_H__
#error "include 'stdafx.h' before including this file for PCH"
#endif
#include "resource.h" // main symbols
And my code is this
// iDEMA.cpp : Defines the exported functions for the DLL application.
//
#include "stdafx.h"
#include "iDEMA.h"
#ifdef _DEBUG
#define new DEBUG_NEW
#endif
#define WIN32_LEAN_AND_MEAN
#define MT4_EXPFUNC __declspec(dllexport)
using namespace std;
BOOL APIENTRY DllMain(HANDLE hModule, DWORD ul_reason_for_call, LPVOID lpReserved)
{
//---
switch (ul_reason_for_call)
{
case DLL_PROCESS_ATTACH:
case DLL_THREAD_ATTACH:
case DLL_THREAD_DETACH:
case DLL_PROCESS_DETACH:
break;
}
//---
return(TRUE);
}
MT4_EXPFUNC double __stdcall iDEMA(const RateInfo* rates, const int rates_total, const int period, const int shift, const ENUM_PRICE applied_price)
{
//---
if (rates == NULL)
{
printf("iDEMA: NULL array\n");
return(0.0);
}
//---
if (rates_total<0 || rates_total<2 * period)
{
printf("iDEMA: wrong rates_total number (%d)\n", rates_total);
return(0.0);
}
//---
if (period<2 || period>100000)
{
printf("iDEMA: wrong period number (%d)\n", period);
return(0.0);
}
//---
if (shift<0 || shift >= rates_total)
{
printf("iDEMA: wrong shift number (%d)\n", shift);
return(0.0);
}
//---
if (applied_price<0 || applied_price>3)
{
printf("iDEMA: wrong applied price (%d)\n", applied_price);
return(0.0);
}
//---
TA_RetCode retCode;
retCode = TA_Initialize();
if (retCode != TA_SUCCESS)
{
printf("TA_LIB initialistion failed (%d)!\n", retCode);
return(0.0);
}
vector<TA_Real> dataArray;
const TA_Real* dataArray_c_pointer = dataArray.data();
// DEMA = ( 2 * EMA(n)) - (EMA(EMA(n)) ), where n= period
for (int nitem = rates_total - 1 - shift - (2 * period); nitem < rates_total - 1 - shift; nitem++)
{
TA_Real value = 0.0;
switch (applied_price)
{
case PRICE_OPEN: value = rates[nitem].open; break;
case PRICE_LOW: value = rates[nitem].low; break;
case PRICE_HIGH: value = rates[nitem].high; break;
case PRICE_CLOSE: value = rates[nitem].close; break;
}
dataArray[nitem] = value;
}
TA_Integer outBegin = 0, outElements = 0;
int beginIndx, endIndx;
beginIndx = endIndx = dataArray.size() - 1;
int array_size = endIndx - beginIndx + 1;
cout << "beginIndx = " << to_string(beginIndx) << endl << "endIndx = " << to_string(endIndx) << endl << "array_size = " << to_string(array_size) << endl;
vector<TA_Real> outDema(array_size, 0.0);
TA_Real* outDema_c_pointer = outDema.data();
retCode = TA_DEMA(beginIndx, endIndx, dataArray_c_pointer, period, &outBegin, &outElements, outDema_c_pointer);
double value = 0.0;
if (retCode == TA_SUCCESS)
{
cout << "outBegin = " << outBegin << " outElements = " << outElements << endl;
int lastElement = outElements - 1;;
cout << "outDema.at(" << to_string(lastElement) << ") = " << to_string(outDema.at(lastElement)) << endl;
delete dataArray_c_pointer;
delete outDema_c_pointer;
value = outDema.at(lastElement);
}
retCode = TA_Shutdown();
return value;
}
I installed the library using nuGet.
Could you help to compile this DLL please.
Thanks in advance.
Update 10/10/15
I removed the package nuGet and used static linking from a different directory.
I'm now getting these linker errors:
Error 2 error LNK1169: one or more multiply defined symbols found C:\Users\Documents\Visual Studio 2013\Projects\iDEMA\Release\iDEMA.dll iDEMA
Error 1 error LNK2005: _DllMain#12 already defined in mfcs120u.lib(dllmodul.obj) C:\Users\Documents\Visual Studio 2013\Projects\iDEMA\iDEMA\* CIL library *(* CIL module *) iDEMA
Still don't understand how to fix them!
Any help will be appreciated.
Thanks.
Try wrapping your header like this:
extern "C"
{
#include "stdafx.h"
#include "iDEMA.h"
}
If VS complains about the extern keyword go to Project Properties > C/C++ > Advanced > Compile As and check Compile as C++.
For the Updated answer, it looks like your compiler is seeing two definitions of the same symbol.
Try using
#include <stdafx.h>
#include <iDEMA.h>
They look in different places. If it doesn't help, try the extern "C" with your old project (before update 10/10/15).
Maybe you've added some dll or lib to your PATH in your first try and after the "Update 10/10/15", you don't need them anymore.
Also read this
answer
and this
MSDN Building Visual C++ page.
Edit:
If possible, create a new project. Maybe, in your attempts, you've messed something.
Managed to get it to link after modifying the header and source files. Here's the final result:
// The following ifdef block is the standard way of creating macros which make exporting
// from a DLL simpler. All files within this DLL are compiled with the IDEMA_EXPORTS
// symbol defined on the command line. This symbol should not be defined on any project
// that uses this DLL. This way any other project whose source files include this file see
// IDEMA_API functions as being imported from a DLL, whereas this DLL sees symbols
// defined with this macro as being exported.
#define WIN32_LEAN_AND_MEAN
#define MT4_EXPFUNC __declspec(dllexport)
#pragma pack(push,1)
struct RateInfo
{
__int64 ctm;
double open;
double low;
double high;
double close;
unsigned __int64 vol_tick;
int spread;
unsigned __int64 vol_real;
};
enum ENUM_PRICE
{
PRICE_OPEN,
PRICE_LOW,
PRICE_HIGH,
PRICE_CLOSE
};
#pragma pack(pop)
// This class is exported from the iDEMA.dll
class MT4_EXPFUNC CiDEMA {
public:
CiDEMA(void);
double iDEMA(RateInfo, int, int, int, ENUM_PRICE);
};
extern MT4_EXPFUNC int niDEMA;
MT4_EXPFUNC int fniDEMA(void);
#include <windows.h>
#include <stdlib.h>
#include <stdio.h>
#include <iostream>
#include <vector>
#include <string>
#include "C:\ta-lib-0.4.0-msvc\ta-lib\c\include\ta_libc.h"
#pragma once
#ifndef __AFXWIN_H__
#error "include 'stdafx.h' before including this file for PCH"
#endif
#include "resource.h" // main symbols
And the source file:
// iDEMA.cpp : Defines the exported functions for the DLL application.
//
#include "stdafx.h"
#include "iDEMA.h"
#ifdef _DEBUG
#define new DEBUG_NEW
#endif
using namespace std;
MT4_EXPFUNC double __stdcall iDEMA(const RateInfo* rates, const int rates_total, const int period, const int shift, const ENUM_PRICE applied_price)
{
//---
if (rates == NULL)
{
printf("iDEMA: NULL array\n");
return(0.0);
}
//---
if (rates_total<0 || rates_total<2 * period)
{
printf("iDEMA: wrong rates_total number (%d)\n", rates_total);
return(0.0);
}
//---
if (period<2 || period>100000)
{
printf("iDEMA: wrong period number (%d)\n", period);
return(0.0);
}
//---
if (shift<0 || shift >= rates_total)
{
printf("iDEMA: wrong shift number (%d)\n", shift);
return(0.0);
}
//---
if (applied_price<0 || applied_price>3)
{
printf("iDEMA: wrong applied price (%d)\n", applied_price);
return(0.0);
}
//---
TA_RetCode retCode;
retCode = TA_Initialize();
if (retCode != TA_SUCCESS)
{
printf("TA_LIB initialistion failed (%d)!\n", retCode);
return(0.0);
}
vector<TA_Real> dataArray;
const TA_Real* dataArray_c_pointer = dataArray.data();
// DEMA = ( 2 * EMA(n)) - (EMA(EMA(n)) ), where n= period
for (int nitem = rates_total - 1 - shift - (2 * period); nitem < rates_total - 1 - shift; nitem++)
{
TA_Real value = 0.0;
switch (applied_price)
{
case PRICE_OPEN: value = rates[nitem].open; break;
case PRICE_LOW: value = rates[nitem].low; break;
case PRICE_HIGH: value = rates[nitem].high; break;
case PRICE_CLOSE: value = rates[nitem].close; break;
}
dataArray[nitem] = value;
}
TA_Integer outBegin = 0, outElements = 0;
int beginIndx, endIndx;
beginIndx = endIndx = dataArray.size() - 1;
int array_size = endIndx - beginIndx + 1;
cout << "beginIndx = " << to_string(beginIndx) << endl << "endIndx = " << to_string(endIndx) << endl << "array_size = " << to_string(array_size) << endl;
vector<TA_Real> outDema(array_size, 0.0);
TA_Real* outDema_c_pointer = outDema.data();
retCode = TA_DEMA(beginIndx, endIndx, dataArray_c_pointer, period, &outBegin, &outElements, outDema_c_pointer);
double value = 0.0;
if (retCode == TA_SUCCESS)
{
cout << "outBegin = " << outBegin << " outElements = " << outElements << endl;
int lastElement = outElements - 1;;
cout << "outDema.at(" << to_string(lastElement) << ") = " << to_string(outDema.at(lastElement)) << endl;
delete dataArray_c_pointer;
delete outDema_c_pointer;
value = outDema.at(lastElement);
}
retCode = TA_Shutdown();
return value;
}
This question already has answers here:
What is an undefined reference/unresolved external symbol error and how do I fix it?
(39 answers)
Closed 8 years ago.
I have a compiling problem in my project. I have read tons of post with this error on the title but I couldn't fix it.
I am receiving this error:
Error 4 error LNK2019: unresolved external symbol "public: class vtkUnstructuredGrid * __thiscall volumerendering::volume(class itk::SmartPointer<class itk::Image<unsigned short,3> >,class itk::SmartPointer<class itk::Image<int,3> >,class std::basic_string<char,struct std::char_traits<char>,class std::allocator<char> >)" (?volume#volumerendering##QAEPAVvtkUnstructuredGrid##V?$SmartPointer#V?$Image#G$02#itk###itk##V?$SmartPointer#V?$Image#H$02#itk###4#V?$basic_string#DU?$char_traits#D#std##V?$allocator#D#2##std###Z) referenced in function __catch$_main$0 a.obj
Error 5 fatal error LNK1120: 1 unresolved externals C:\Users\SERAP\Desktop\programlar\vnewb\Debug\DICOM.exe
The code is the following:
a.cpp
#if defined(_MSC_VER)
#pragma warning ( disable : 4786 )
#endif
#ifdef __BORLANDC__
#define ITK_LEAN_AND_MEAN
#endif
#include "volumerendering.h"
#include "itkImage.h"
#include "itkImageSeriesReader.h"
#include "itkImageFileWriter.h"
#include "itkNumericSeriesFileNames.h"
#include "itkPNGImageIO.h"
#include "itkTIFFImageIO.h"
#include <vtkXMLUnstructuredGridWriter.h>
// Software Guide : EndCodeSnippet
#include <list>
#include <fstream>
#include <stdio.h>
#include <stdlib.h>
#include<itkRGBPixel.h>
#include "itkThresholdImageFilter.h"
#include "itkGDCMSeriesFileNames.h"
#include "itkGDCMImageIO.h"
#include "vtkRenderWindowInteractor.h"
#include "vtkSmartPointer.h"
#include "vtkImageActor.h"
#include "vtkInteractorStyleImage.h"
#include "vtkRenderer.h"
#include"vtkImageViewer2.h"
#include <vtkSliderWidget.h>
#include <vtkSliderRepresentation2D.h>
#include <vtkSTLWriter.h>
// Software Guide : EndCodeSnippet
int main( int argc, char ** argv )
{
// Verify the number of parameters in the command line
if( argc < 6 )
{
std::cerr << "Usage: " << std::endl;
std::cerr << argv[0] << " firstSliceValue lastSliceValue outputImageFile OrjinalDicomDirectory Alanhesabı(txt)DosyasıAdı" << std::endl;
return EXIT_FAILURE;
}
typedef unsigned short PixelType;
const unsigned int Dimension = 3;
typedef itk::Image< PixelType, Dimension > ImageType;
// Software Guide : EndCodeSnippet
// Software Guide : BeginLatex
//
// The image type is used as a template parameter to instantiate
// the reader and writer.
//
// \index{itk::ImageSeriesReader!Instantiation}
// \index{itk::ImageFileWriter!Instantiation}
//
// Software Guide : EndLatex
// Software Guide : BeginCodeSnippet
typedef itk::ImageSeriesReader< ImageType > ReaderType;
ReaderType::Pointer reader = ReaderType::New();
const unsigned int first = atoi( argv[1] );
const unsigned int last = atoi( argv[2] );
typedef itk::NumericSeriesFileNames NameGeneratorType;
NameGeneratorType::Pointer nameGenerator = NameGeneratorType::New();
// Software Guide : EndCodeSnippet
// Software Guide : BeginLatex
//
// The filenames generator requires us to provide a pattern of text for the
// filenames, and numbers for the initial value, last value and increment to be
// used for generating the names of the files.
//
// Software Guide : EndLatex
// Software Guide : BeginCodeSnippet
nameGenerator->SetSeriesFormat( "trabekuler%03d.tiff" );
nameGenerator->SetStartIndex( first );
nameGenerator->SetEndIndex( last );
nameGenerator->SetIncrementIndex( 1 );
reader->SetImageIO( itk::TIFFImageIO::New() );
//reader->SetImageIO( itk::PNGImageIO::New() );
reader->SetFileNames( nameGenerator->GetFileNames() );
reader->Update();
typedef int PixelType1;
const unsigned int Dimension1 = 3;
typedef itk::Image< PixelType1, Dimension1 > ImageType1;
typedef itk::ImageSeriesReader< ImageType1 > ReaderType1;
typedef itk::GDCMImageIO ImageIOType;
typedef itk::GDCMSeriesFileNames NamesGeneratorType;
ImageIOType::Pointer gdcmIO = ImageIOType::New();
NamesGeneratorType::Pointer namesGenerator1 = NamesGeneratorType::New();
namesGenerator1->SetInputDirectory( argv[4] );
const ReaderType1::FileNamesContainer & filenames1 =
namesGenerator1->GetInputFileNames();
unsigned int numberOfFilenames1 = filenames1.size();
std::cout << numberOfFilenames1 << std::endl;
for(unsigned int fni1 = 0; fni1<numberOfFilenames1; fni1++)
{
std::cout << "filename # " << fni1 << " = ";
std::cout << filenames1[fni1] << std::endl;
}
ReaderType1::Pointer reader1 = ReaderType1::New();
reader1->SetImageIO( gdcmIO );
reader1->SetFileNames( filenames1 );
try
{
// Software Guide : BeginCodeSnippet
reader1->Update();
// Software Guide : EndCodeSnippet
}
catch (itk::ExceptionObject &excp)
{
std::cerr << "Exception thrown while writing the image" << std::endl;
std::cerr << excp << std::endl;
return EXIT_FAILURE;
}
ImageType1::Pointer image=reader1->GetOutput();
typedef itk::MetaDataDictionary DictionaryType;
const DictionaryType & dictionary = gdcmIO->GetMetaDataDictionary();
typedef itk::MetaDataObject< std::string > MetaDataStringType;
std::string entryId = "0010|0010";
DictionaryType::ConstIterator end = dictionary.End();
DictionaryType::ConstIterator tagItr = dictionary.Find( entryId );
if( tagItr == end )
{
std::cerr << "Tag " << entryId;
std::cerr << " not found in the DICOM header" << std::endl;
return EXIT_FAILURE;
}
MetaDataStringType::ConstPointer entryvalue =
dynamic_cast<const MetaDataStringType *>( tagItr->second.GetPointer() );
std::string filename2 = argv[5];
if( entryvalue )
{
std::string tagvalue = entryvalue->GetMetaDataObjectValue();
std::cout << "Patient's Name (" << entryId << ") ";
std::cout << " is: " << tagvalue << std::endl;
std::ofstream myfile;
myfile.open(filename2.c_str(),std::ios::app);
myfile<< "Patient's Name: "<<tagvalue<<std::endl;
myfile .close();
}
else
{
std::cerr << "Entry was not of string type" << std::endl;
return EXIT_FAILURE;
}
//hacim ve alan hesabi
ImageType::SizeType si;
si=reader->GetOutput()->GetLargestPossibleRegion().GetSize();
ImageType::IndexType pixelIndex;
ImageType1::SpacingType sp;
sp=image->GetSpacing();
std::ofstream myfile;
myfile.open(filename2.c_str(),std::ios::app);
myfile<< "\n"<<std::endl;
myfile<< "Areas: "<<std::endl;
myfile<< "\n"<<std::endl;
double alann=sp[1]*sp[0];
for(int k=si[2]-1;k>-1;k--)
{
int sayii=0;
for(int i=0;i<si[0];i++)
{
for(int j=0;j<si[1];j++)
{
pixelIndex[0] = i; // x position
pixelIndex[1] =j ; // y position
pixelIndex[2]= k;
if(reader->GetOutput()->GetPixel(pixelIndex)==255)
{
sayii=sayii+1;
}
}
}
myfile<< "filename: "<<filenames1[k]<<" "<<"Area : "<<alann*sayii<<" mm_2"<<std::endl;
}
myfile .close();
// end hacim
volumerendering * vol = new volumerendering;
std::string filename = argv[3];
vtkSmartPointer<vtkXMLUnstructuredGridWriter> writer =
vtkSmartPointer<vtkXMLUnstructuredGridWriter>::New();
writer->SetFileName(filename.c_str());
writer->SetInput( vol->volume(reader->GetOutput(),image,filename2));
writer->Write();
return EXIT_SUCCESS;
}
volumerendering.cpp
#ifndef _volumerendering_cpp
#define _volumerendering_cpp
#include"volumerendering.h"
#include <vtkSmartPointer.h>
#include <vtkDataSetMapper.h>
#include <vtkActor.h>
#include <vtkRenderWindow.h>
#include <vtkRenderer.h>
#include <vtkRenderWindowInteractor.h>
#include <vtkPoints.h>
#include <vtkVoxel.h>
#include <vtkUnstructuredGrid.h>
#include <vtkParticleReader.h>
#include <vtkProperty.h>
#include <vtkPolyData.h>
#include <vtkCellArray.h>
#include <vtkDataSetSurfaceFilter.h>
#include <vtkPointSource.h>
#include <vtkPointData.h>
#include <vtkSTLWriter.h>
#include <vtkVertexGlyphFilter.h>
#include<vtkPolyDataWriter.h>
vtkUnstructuredGrid* volumerendering::volume(itk::Image<unsigned short,3>::Pointer image,itk::Image<int,3>::Pointer image1,std::string outt )
{
vtkUnstructuredGrid *ug = vtkUnstructuredGrid::New();
vtkSmartPointer<vtkPoints> points =vtkSmartPointer<vtkPoints>::New();
typedef itk::Image< unsigned short, 3 > ImageType;
typedef itk::Image< int, 3 > ImageType1;
ImageType::SizeType si;
si=image->GetLargestPossibleRegion().GetSize();
ImageType::IndexType pixelIndex;
ImageType1::SpacingType sp;
sp=image1->GetSpacing();
// hacim vee alan hesapları
double hacim=sp[1]*sp[0]*sp[2];
//hacim ve alan hesabi son
int fr=0;
int hacimsayii=0;
for(int i=0;i<si[0];i++)
{
for(int j=0;j<si[1];j++)
{
for(int k=0;k<si[2];k++)
{
pixelIndex[0] = i; // x position
pixelIndex[1] =j ; // y position
pixelIndex[2]= k;
if(image->GetPixel(pixelIndex)==255)
{hacimsayii=hacimsayii+1;
float a1[]={i*sp[0],j*sp[1],k*sp[2]};
float a2[]={(i+1)*sp[0],j*sp[1],k*sp[2]};
float a3[]={i*sp[0],(j+1)*sp[1],k*sp[2]};
float a4[]={(i+1)*sp[0],(j+1)*sp[1],k*sp[2]};
float a5[]={i*sp[0],j*sp[1],(k+1)*sp[2]};
float a6[]={(i+1)*sp[0],j*sp[1],(k+1)*sp[2]};
float a7[]={i*sp[0],(j+1)*sp[1],(k+1)*sp[2]};
float a8[]={(i+1)*sp[0],(j+1)*sp[1],(k+1)*sp[2]};
points->InsertPoint(fr,a1);
points->InsertPoint(fr+1,a2);
points->InsertPoint(fr+2,a3);
points->InsertPoint(fr+3,a4);
points->InsertPoint(fr+4,a5);
points->InsertPoint(fr+5,a6);
points->InsertPoint(fr+6,a7);
points->InsertPoint(fr+7,a8);
fr=fr+8;
}
}
}
}
std::ofstream myfile;
myfile.open(outt.c_str(),std::ios::app);
myfile<< "\n"<<std::endl;
myfile<< "Volume "<<std::endl;
myfile<< "\n"<<std::endl;
myfile<< "Total Volume= "<<hacim*hacimsayii<<" mm_3"<<std::endl;
myfile .close();
static int ptr[8];
int tt=0;
int cti=points->GetNumberOfPoints();
for (int i=0;i<cti/8 ;i++)
{
for (int iy=0;iy<1;iy++)
{
ptr[0]=iy+tt; ptr[1]=iy+tt+1; ptr[2]=iy+tt+2; ptr[3]=iy+tt+3;
ptr[4]=iy+tt+4; ptr[5]=iy+tt+5; ptr[6]=iy+tt+6; ptr[7]=iy+tt+7;
ug->InsertNextCell(VTK_VOXEL,8,ptr);
tt=tt+8;
}
}
ug->SetPoints(points);
/* vtkSmartPointer<vtkDataSetMapper> mapper =
vtkSmartPointer<vtkDataSetMapper>::New();
mapper->SetInput(ug);
vtkSmartPointer<vtkActor> actor =
vtkSmartPointer<vtkActor>::New();
actor->SetMapper(mapper);
vtkSmartPointer<vtkRenderWindow> renderWindow =
vtkSmartPointer<vtkRenderWindow>::New();
vtkSmartPointer<vtkRenderer> renderer =
vtkSmartPointer<vtkRenderer>::New();
renderWindow->AddRenderer(renderer);
renderer->AddActor(actor);
renderer->ResetCamera();
vtkSmartPointer<vtkRenderWindowInteractor> renderWindowInteractor =
vtkSmartPointer<vtkRenderWindowInteractor>::New();
renderWindowInteractor->SetRenderWindow(renderWindow);
renderWindow->Render();
renderWindowInteractor->Start();*/
return ug;
}
#endif
volumerendering.h
#ifndef __volumerendering_h
#define __volumerendering_h
#include"vtkUnstructuredGrid.h"
#include"itkImage.h"
#include "itkImageSeriesReader.h"
class volumerendering
{
public:
vtkUnstructuredGrid* volume(itk::Image<unsigned short,3>::Pointer image,itk::Image<int,3>::Pointer image1,std::string outt );
};
#endif
thanks
volumerendering.cpp has to be compiled with the project.
But I do not see anything that prevent volumerendering::volume from being defined, so it may be a project configuration problem ?
Make sure that volumerendering.cpp is compiled at the same time than a.cpp.
I am getting these errors:
Error 2 error LNK2005: "class std::basic_string<char,struct std::char_traits<char>,class std::allocator<char> > __cdecl ToString(int)" (?ToString##YA?AV?$basic_string#DU?$char_traits#D#std##V?$allocator#D#2##std##H#Z) already defined in Sender.obj C:\CSE687\Project3_TT_1\Repository\Repository.obj
Error 3 error LNK2005: "private: static int Sender::count" (?count#Sender##0HA) already defined in Sender.obj C:\CSE687\Project3_TT_1\Repository\Repository.obj
Error 4 error LNK1169: one or more multiply defined symbols found C:\CSE687\Project3_TT_1\Debug\Repository.exe
from these three pieces of code:
#ifndef SEND_H
#define SEND_H
/////////////////////////////////////////////////////////////////
// Sender.cpp - Demonstration of concurrent socket connectors //
// ver 2 //
// Jim Fawcett, CSE687 - Object Oriented Design, Spring 2013 //
/////////////////////////////////////////////////////////////////
/*
* This Sender expects to write lines of text only.
* So message framing is done by lines.
*
* For HTTP like protocols the Sender should send lines for each
* header attribute and bytes in the body, if there is one,
* specified by a last header line something like:
* content_length : 1024
* where 1024 is a stand-in for whatever you want your block
* size to be.
*
*/
/*
* Required files:
* - Sender.cpp, Sockets.h, Sockets.cpp,
* Threads.h, Threads.cpp, Locks.h, Locks.cpp
* BlockingQueue.h, BlockingQueue.cpp
*
* Maintanence History:
* ver 1.1 - 30 Mar 2013
* - changed Sendthread from terminating to default
* - minor changes to error handling
* ver 1.0 - 29 Mar 2013
* - first release
*/
#include "../sockets/Sockets.h"
#include "../Threads/Threads.h"
#include "../Threads/Locks.h"
#include "../BlockingQueue/BlockingQueue.h"
#include <string>
#include <iostream>
#include <sstream>
///////////////////////////////////////////////////
// SendThread thread
class SendThread : public threadBase
{
public:
SendThread(Socket s, BlockingQueue<std::string>& q) : s_(s), q_(q) {}
std::string& status() { return status_; }
private:
void run()
{
status_ = "good";
doLog("send thread running");
std::string msg;
do
{
doLog("send thread enqing msg");
msg = q_.deQ();
if(!s_.writeLine(msg))
{
sout << "\n bad status in sending thread";
status_ = "bad";
break;
}
} while(msg != "stop");
s_.disconnect();
}
std::string status_;
Socket s_;
BlockingQueue<std::string>& q_;
};
std::string ToString(int i)
{
std::ostringstream conv;
conv << i;
return conv.str();
}
class Sender
{
public:
Sender() {};
Sender(int numMsgs) : numMsgs_(numMsgs) { myCount = ++count; }
int id() { return myCount; }
void start(std::string ip, int port)
{
sout << locker << "\n Sender #" << id() << " started" << unlocker;
pSt = new SendThread(s_, q_);
pSt->start();
if(!s_.connect(ip, port))
{
sout << locker << "\n couldn't connect to " << ip << ":" << port << "\n\n" << unlocker;
delete pSt;
return;
}
else
{
std::string logMsg = "\n connected to " + ip + ":" + ToString(port);
doLog(logMsg.c_str());
}
doLog("starting Sender");
std::string msg;
for(int i=0; i<numMsgs_; ++i)
{
doLog("sending message");
msg = "sender#" + ToString(id()) + ": msg#" + ToString(i);
sout << locker << "\n " << msg.c_str() << unlocker;
q_.enQ(msg);
::Sleep(10 * id()); // sleep time increases with each addition Sender
if(pSt->status() == "bad")
break;
}
q_.enQ("stop");
msg = "sender#" + ToString(id()) + ": stop";
sout << "\n " + msg;
pSt->join();
delete pSt;
}
private:
Socket s_;
BlockingQueue<std::string> q_;
SendThread* pSt;
static int count;
int myCount;
int numMsgs_;
};
int Sender::count = 0;
///////////////////////////////////////////////////
// DemoThread is used to get two or more senders
// running concurrently from a single process, to
// make testing easier.
class DemoThread : public threadBase
{
public:
DemoThread(Sender sndr) : sndr_(sndr) {}
private:
void run()
{
sndr_.start("127.0.0.1", 8080);
}
Sender sndr_;
};
#endif
and:
#ifndef REPOS_H
#define REPOS_H
/////////////////////////////////////////////////////////////////
// Recepository.h - Demonstration of repository action using a //
// socket reciever with concurrent clients //
// //
// Thomas P. Taggart //
// tptaggarsyr.edu //
// CSE687, Object Oriented Design, Spring 2013 //
/////////////////////////////////////////////////////////////////
/*
* Required files:
* - Reciever.h, Receiver.cpp, Sockets.h, Sockets.cpp,
* Threads.h, Threads.cpp, Locks.h, Locks.cpp
* BlockingQueue.h, BlockingQueue.cpp
*/
#include "../Sockets/Sockets.h"
#include "../Threads/Threads.h"
#include "../Threads/Locks.h"
#include "../Receiver/Receiver.h"
#include "../Sender/Sender.h"
#include "../BlockingQueue/BlockingQueue.h"
#include <string>
class Repository
{
public:
Repository() {};
~Repository() {};
Sender* getSender();
Receiver* getReceiver();
private:
Sender* repoSender;
Receiver* repoReceiver;
};
#endif
and:
/////////////////////////////////////////////////////////////////
// Recepository.cpp - Demonstration of repository action using //
// a socket reciever with concurrent clients //
// //
// Thomas P. Taggart //
// tptaggarsyr.edu //
// CSE687, Object Oriented Design, Spring 2013 //
/////////////////////////////////////////////////////////////////
/*
* Required files:
* - Reciever.h, Receiver.cpp, Sockets.h, Sockets.cpp,
* Threads.h, Threads.cpp, Locks.h, Locks.cpp
* BlockingQueue.h, BlockingQueue.cpp
*/
#include "../Repository/Repository.h"
#include <string>
using namespace std;
Sender* Repository::getSender()
{
return repoSender;
}
Receiver* Repository::getReceiver()
{
return repoReceiver;
}
int main()
{
int ret = 0;
try
{
Repository repos;
repos.getReceiver()->start(8080);
}
catch(std::exception& ex)
{
std::cout << "\n\n " << ex.what();
ret = 1;
}
catch(...)
{
sout << "\n something bad happened";
ret = 1;
}
sout << "\n\n";
return ret;
}
I have not for the life of me been able to figure out how to avoid it. the 'extern' solution doesn't seem to work and #ifndef headers area already used.
Any advice is greatly appreciated.
Tom
You're breaking the ODR - either make std::string ToString(int i) inline or move it to an implementation file.