I face a error of "multiple definition of "
I got 3 files, namely currency.h, currency.cpp,main.cpp
At currencyConverter.h under currencyConverter class
I did
using namespace std;
class currencyConverter
{
string result;
stringstream ss;
size_t found,found2;
public:
void getInbetween(string,string);
};
#endif /* CURRENCYCONVERTER_H */
Then at currencyConverter.cpp I did
#include "currencyConverter.h"
void currencyConverter::getInbetween(string selection,string str2,string str3,string sdata)
{
buffer[result.length()] = '\0'; //insert '\0'
char * pch;
pch = strtok (buffer," ");
}
void currencyConverter::webparser(const string siteurl,const string filename)
{
ss << "lynx -dump '" << siteurl << "' > " << filename;
}
string currencyConverter::userOption()
{
//some code
return selection;
}
at main2.cpp
#include<iostream>
#include"currencyConverter.cpp"
using namespace std;
int main() {
currencyConverter c;
string exitstr;
if(selection!="6")
{
c.webparser(parsePage,"file.txt");
//now perform searchstring
c.searchString(selection,"file.txt");
}
}while (1);
return 0;
}
This is my make file
# ExampleTests Project
SRCS = main2.cpp
HDRS =
PROJ = main
CC = g++
OBJS = $(SRCS:.cpp=.o)
APP = $(PROJ).exe
CFLAGS = -c -g -Wall -I/opt/local/include
ifeq (,$(findstring CYGWIN,$(shell uname)))
LIBS = -lcppunit -ldl
all: $(APP)
$(APP): $(OBJS)
$(CC) $(LDFLAGS) $(OBJS) -o $(APP) $(LIBS)
clean:
rm -f *.o $(APP)
But i receive this error on compiler
How to get this fix.. I did not use it twice. I pasted part of my currencyConverter.cpp with the function webparser, is there a error in the way i call my function at main2.cpp ?
rm -f *.o main.exe
CLEAN SUCCESSFUL (total time: 86ms)
g++ -c -o main2.o main2.cpp
td::char_traits, std::allocator >)':
currencyConverter.cpp:(.text+0xcec): multiple definition of `currencyConverter::webparser(std::basic_string, std::allocator >, std::basic_string, std::allocator >)'
main2.o:main2.cpp:(.text+0xcec): first defined here
collect2: ld returned 1 exit status
make: * [main.exe] Error 1
Include a header file, not a cpp:
#include"currencyConverter.cpp"
should be
#include"currencyConverter.h"
in your main2.cpp
Related
While making a simple test case I met with another problem. Please help me.
Here are the files.
<<< bar.cpp >>>
#include <stdint.h>
#include <stdio.h>
extern "C" {
uint64_t var_from_lib;
}
class BC;
class BC {
public:
void bar(void);
BC();
~BC();
};
BC::BC()
{
}
BC::~BC()
{
}
void BC::bar(void)
{
printf("class function : var_from_lib = %lx\n", var_from_lib);
}
extern "C" {
void bar(void)
{
printf("global function : var_from_lib = %lx\n", var_from_lib);
BC tmp;
tmp.bar();
}
}
<<< main1.c >>>
#include <dlfcn.h>
#include <stdio.h>
#include <stdlib.h>
#include <stdint.h>
extern uint64_t var_from_lib; // = 0x12345678;
int main1(void)
{
void * dlh = dlopen("./libbar.so", RTLD_NOW);
if (!dlh) {
fprintf(stderr, "%s\n", dlerror());
exit(EXIT_FAILURE);
}
void (*bar)(void) = dlsym(dlh,"bar");
if (!bar) {
fprintf(stderr, "%s\n", dlerror());
exit(EXIT_FAILURE);
}
var_from_lib = 0x12341111;
bar();
return 0;
}
<<< main2.c >>>
#include <dlfcn.h>
#include <stdio.h>
#include <stdlib.h>
#include <stdint.h>
extern uint64_t var_from_lib; // = 0x12345678;
int main2(void)
{
void * dlh = dlopen("./libbar.so", RTLD_NOW);
if (!dlh) {
fprintf(stderr, "%s\n", dlerror());
exit(EXIT_FAILURE);
}
void (*bar)(void) = dlsym(dlh,"bar");
if (!bar) {
fprintf(stderr, "%s\n", dlerror());
exit(EXIT_FAILURE);
}
var_from_lib = 0x12342222;
bar();
return 0;
}
<<< main.c >>>
#include <dlfcn.h>
#include <stdio.h>
#include <stdlib.h>
#include <stdint.h>
extern uint64_t var_from_lib; // = 0x12345678;
uint64_t __attribute__((weak)) var_from_lib; // = 0x12345678;
extern int main1();
extern int main2();
int main(int argc, char *argv[])
{
if (atoi(argv[1]) == 1) {
main1();
}
else if (atoi(argv[1]) == 2) {
main2();
}
else {
printf("usage : main [1|2]\n");
}
return 0;
}
<<< Makefile >>>
.PHONY: all clean test
LDEXTRAFLAGS ?=
all: prog
%.o: %.c
gcc -c -Wall -fpic -o $# -ldl $<
%.o: %.cpp
g++ -c -Wall -fpic -o $# $<
libbar.so: bar.o
gcc -shared -o $# $<
main: main.o main1.o main2.o
gcc -c -Wall -o $# $< -rdynamic
prog: main.o main1.o main2.o | libbar.so
gcc $(LDEXTRAFLAGS) -o $# $^ -ldl
clean:
rm -f *.o *.so prog
Here is the execution result.
ckim#ckim-ubuntu:~/testdir$ make
gcc -c -Wall -fpic -o main.o -ldl main.c
gcc -c -Wall -fpic -o main1.o -ldl main1.c
gcc -c -Wall -fpic -o main2.o -ldl main2.c
g++ -c -Wall -fpic -o bar.o bar.cpp
gcc -shared -o libbar.so bar.o
gcc -o prog main.o main1.o main2.o -ldl
ckim#ckim-ubuntu:~/testdir$ prog 1
./libbar.so: undefined symbol: __gxx_personality_v0
How can I remove the error?
How can I remove the error?
Link your application with C++ library. Link with g++ or GLOBAL dlopen the libstdc++.so library. Overall, gcc -shared -o libbar.so bar.o should be g++ -shared -o libbar.so bar.o - it's a C++ library. gcc -Wl,--no-undefined -shared -o libbar.so bar.o catches the problem.
How do I run a non-legacy PassManager? I have tried doing the following but there is some exception thrown when trying to invalidate the analysis manager in the run function. Is there something else I should do for initialization?
llvm::AnalysisManager<Module> mm;
PassBuilder builder;
auto pm = builder.buildModuleOptimizationPipeline(PassBuilder::OptimizationLevel::O3);
pm.run(module, mm );
These snippets illustrate how to run and setup to run modern custom function and module pass on some .c/.cpp file... complete with a makefile. This works for LLVM 6 which is pretty recent (march 2018). It does not use the legacy pass manager.
HelloWorld.cpp:
#include <llvm/Pass.h>
#include <llvm/IR/Function.h>
#include <llvm/IR/Module.h>
#include <llvm/Support/raw_ostream.h>
namespace {
struct Hello : public llvm::FunctionPass {
static char ID;
Hello() : llvm::FunctionPass{ID} {}
bool runOnFunction(llvm::Function &F) override {
llvm::errs() << "Hello ";
llvm::errs().write_escaped(F.getName()) << "\n";
return false;
}
};
struct Hello2 : public llvm::ModulePass {
static char ID;
Hello2() : llvm::ModulePass{ID} {}
bool runOnModule(llvm::Module &M) override {
llvm::errs() << "Name of the module ", llvm::errs().write_escaped(M.getName()) << "\n";
for(auto iter = M.getFunctionList().begin(); iter != M.getFunctionList().end(); ++iter) {
llvm::errs() << "Function name:" << iter->getName() << "\n";
}
return false;
}
};
}
char Hello::ID = 0;
static llvm::RegisterPass<Hello> X("Hello",
"Hello World Pass",
false,
false
);
char Hello2::ID = 1;
static llvm::RegisterPass<Hello2> Y("Hello2",
"Hello World2 pass",
false,
false
);
Corresponding makefile:
LLVM_VERSION=
LLVM_INCLUDEDIR = `llvm-config-6.0 --includedir`
LLVM_FLAGS = `llvm-config-6.0 --cxxflags --ldflags --system-libs --libs all`
CXX = clang++-6.0
CXXFLAGS = -g -std=c++11 -O3 -I $(LLVM_INCLUDEDIR) -I $(LLVM_INCLUDEDIR)
Hello.so:
$(CXX) -fPIC $(CXXFLAGS) HelloWorld.cpp $(LLVM_FLAGS) -shared -o Hello.so
Hello: Hello.so
testfile:
clang++-6.0 -emit-llvm -c test.cpp -o test.bc
runFunctionPassOnTestFile: Hello testfile
opt-6.0 -load ./Hello.so -Hello < test.bc > /dev/null
runModulePassOnTestfile: Hello testfile
opt-6.0 -load ./Hello.so -Hello2 < test.bc > /dev/null
clean:
rm *.o *.so *.out *~
DBG:
#echo LLVM INCLUDE DIRS $(LLVM_INCLUDEDIR) $(test)
A simple file to test everything on, test.cpp:
#include <stdio.h>
#include <stdlib.h>
int a = 4;
int c = 5;
int d = 6;
int e = 7;
int bar() { int *a = (int*) malloc(4); e = 1; return 1;}
int foo() { return 2; }
int barfoo() { return 3; }
int main() {
printf("Testing testing\n");
return 0;
}
This is a follow-up question to this one.
I fixed double free and memory corruption by adding copy constructor and assignment constructor to class File and Buffer. But that remote server reports there is segmentation fault. Is there any way to cause class File or Buffer segment fault? I think segment fault is normally related to stack. But I don't have stack operation in these 2 classes.
Buffer.h
#ifndef __BUFFER_H__
#define __BUFFER_H__
#include <stdlib.h>
#include <cerrno>
#include <stdio.h>
class Buffer
{
private:
char * buffer;
int size;
Buffer(const Buffer &);
Buffer& operator=(const Buffer &);
public:
Buffer(int size);
~Buffer();
void reverse(int size);
friend class File;
};
#endif
Buffer.cc:
#include "Buffer.h"
#include "Exception.h"
Buffer::Buffer(int size)
{
this -> size = size;
this -> buffer = (char *)malloc(size);
if(this -> buffer == NULL)
throw Exception(errno);
}
Buffer::~Buffer()
{
// // if(this -> buffer != NULL)
// {
free(this -> buffer);
// this -> buffer = NULL;
// }
}
void Buffer::reverse(int size)
{
char tmp;
int i;
char * tmpb = this -> buffer;
for(i = 0; i < size / 2; i++)
{
tmp = tmpb[i];
tmpb[i] = tmpb[size - i - 1];
// printf("exchange %x with %x\n", tmp & 0xff, tmpb[i] & 0xff);
tmpb[size - i - 1] = tmp;
}
}
File.h:
#ifndef __FILE_H__
#define __FILE_H__
#include "Buffer.h"
#include "Exception.h"
#include <stdio.h>
#include <cerrno>
class File
{
private:
FILE * f;
File(const Buffer &);
File& operator=(const File &);
public:
int whence;
// Note: opening the same file twice for writing ("w")
// at the same time is forbidden
File(const char* name, const char *mode);
~File();
int read(Buffer& buffer, int size);
void write(Buffer& buffer, int size);
void seek(int pos);
void close();
// void seek(long offset, int whence);
long size();
};
#endif
File.cc:
#include "File.h"
File::File(const char* name, const char *mode)
{
f = fopen(name, mode);
if(f == NULL)
throw Exception(errno);
}
File::~File()
{
if(f != NULL)
fclose(f);
}
int File::read(Buffer& buffer, int size)
{
clearerr(this -> f);
size_t tmp;
tmp = fread(buffer.buffer, 1, size, this -> f);
// printf("%ld bytes read\n", tmp);
// for(int i = 0; i < tmp; i++)
// printf("%x ", buffer.buffer[i] & 0xff);
// printf("\n");
if(feof(this -> f) != 0)
return EOF;
if(ferror(this -> f) != 0)
throw Exception(errno);
return tmp;
}
void File::write(Buffer& buffer, int size)
{
size_t tmp;
clearerr(this -> f);
tmp = fwrite(buffer.buffer, 1, size, this -> f);
// printf("%ld bytes written\n", tmp);
// for(int i = 0; i < tmp; i++)
// printf("%x ", buffer.buffer[i] & 0xff);
// printf("\n");
if(ferror(this -> f) != 0)
throw Exception(errno);
}
void File::seek(int pos)
{
int ret = fseek(this -> f, pos, this -> whence);
if(ret != 0)
throw Exception(errno);
}
void File::close()
{
int tmp;
if(this -> f != NULL)
tmp = fclose(this -> f);
this -> f = NULL;
if(tmp != 0)
throw Exception(errno);
}
long File::size()
{
if(fseek(this -> f, 0, SEEK_END) != 0)
throw Exception(errno);
long tmp = ftell(this -> f);
if(tmp == -1)
throw Exception(errno);
if(fseek(this -> f, 0, SEEK_SET) != 0)
throw Exception(errno);
return tmp;
}
NOTE: I have to use C style code. Otherwise I would fail the server test. That is a hard requirement. Well, you may think this requirement is silly. But this is the requirement. Maybe one point is learning the bad while someone mixing C and C++.
The server provides a main function to test my implementation. Just compile using make. The result is a program named rcopy which reverses content of a file byte by byte and then outputs to a new file.
Here is the detailed error output:
make: Entering directory `/home/vmcheck/testhome/co/rcopy'
g++ -c rcopy.cc
g++ -c Buffer.cc
g++ -c Exception.cc
g++ -c File.cc
g++ rcopy.o Buffer.o Exception.o File.o -o rcopy
make: Leaving directory `/home/vmcheck/testhome/co/rcopy'
======== COMPILING AGAINST OUR TESTS ========
g++ -c -Wall -I./ t1.cc -ot1.o
g++ -ot1 t1.o Buffer.o Exception.o File.o
g++ -c -Wall -I./ t2.cc -ot2.o
g++ -ot2 t2.o Buffer.o Exception.o File.o
g++ -c -Wall -I./ t3.cc -ot3.o
g++ -ot3 t3.o Buffer.o Exception.o File.o
g++ -c -Wall -I./ t4.cc -ot4.o
g++ -ot4 t4.o Buffer.o Exception.o File.o
g++ -c -Wall -I./ t5.cc -ot5.o
g++ -ot5 t5.o Buffer.o Exception.o File.o
g++ -c -Wall -I./ t6.cc -ot6.o
g++ -ot6 t6.o Buffer.o Exception.o File.o
g++ -c -Wall -I./ t7.cc -ot7.o
g++ -ot7 t7.o Buffer.o Exception.o File.o
g++ -c -Wall -I./ f1.cc -of1.o
gcc failed_read.c -ldl -shared -fPIC -o failed_read.so
gcc failed_write.c -ldl -shared -fPIC -o failed_write.so
failed_write.c:5:7: warning: conflicting types for built-in function ‘fwrite’ [enabled by default]
g++ -of1 f1.o Buffer.o Exception.o File.o
g++ -c -Wall -I./ f2.cc -of2.o
g++ -of2 f2.o Buffer.o Exception.o File.o
========= TESTING RCOPY ==========
Run: large file
size of input file: 16473
Run: small file
size of input file: 0
========= TESTING EXCEPTION BEHAVIOUR ==========
*** Test 1 ***
*** Test 2 ***
*** Test 3 ***
bash: line 1: 22041 Segmentation fault ./t3
FAILED
The bash script isn't source of the segment fault. I can confirm this. Noted that the test serve could provide many various versions of buggy main to test File, Buffer and Exception.
A possible source of crash are the read and write methods, when called with invalid parameters. For instance, read can be called with a buffer having a size 10, but the function read is requested to read 20 bytes. In this case, you will overflow your buffer.
You have two solutions: either you change your buffer class to be able to resize dinamically, either you read/write up to the maximal size of the buffer, for instance:
tmp = fread(buffer.buffer, 1, min(size, buffer.size), this -> f);
It goes the same for the write.
I was trying the sample codes under opencv3.0.0-alpha while I encountered the following error:
ps#hp-pavilion:~/cvit/opencv_projects$ make stitch
g++ `pkg-config --cflags opencv` -o stitch stitch.cpp `pkg-config --libs opencv`
/usr/lib/gcc/x86_64-linux-gnu/5/../../../x86_64-linux-gnu/crt1.o: In function `_start':
/build/glibc-qbmteM/glibc-2.21/csu/../sysdeps/x86_64/start.S:114: undefined reference to `main'
collect2: error: ld returned 1 exit status
makefile:5: recipe for target 'stitch' failed
make: *** [stitch] Error 1
I had simply copy-pasted the stitching.cpp file from opencv/samples/cpp and renamed and placed it as stitch.cpp in my projects folder where I also have my makefile. The makefile looks like :
CFLAGS = `pkg-config --cflags opencv`
LIBS = `pkg-config --libs opencv`
% : %.cpp
g++ $(CFLAGS) -o $# $< $(LIBS)
I compile .cpp files for instance temp.cpp simply by
make temp
and it works perfectly every time. But with this particular stitching code, the error pops-up each time. Here is the sample code -
#include <iostream>
#include <fstream>
#include "opencv2/imgcodecs.hpp"
#include "opencv2/highgui.hpp"
#include "opencv2/stitching.hpp"
using namespace std;
using namespace cv;
bool try_use_gpu = false;
vector<Mat> imgs;
string result_name = "stitch_result.jpg";
void printUsage();
int parseCmdArgs(int argc, char** argv);
int main(int argc, char* argv[])
{
int retval = parseCmdArgs(argc, argv);
if (retval) return -1;
Mat pano;
Stitcher stitcher = Stitcher::createDefault(try_use_gpu);
Stitcher::Status status = stitcher.stitch(imgs, pano);
if (status != Stitcher::OK)
{
cout << "Can't stitch images, error code = " << int(status) << endl;
return -1;
}
imwrite(result_name, pano);
return 0;
}
void printUsage()
{
cout <<
"Rotation model images stitcher.\n\n"
"stitching img1 img2 [...imgN]\n\n"
"Flags:\n"
" --try_use_gpu (yes|no)\n"
" Try to use GPU. The default value is 'no'. All default values\n"
" are for CPU mode.\n"
" --output <result_img>\n"
" The default is 'result.jpg'.\n";
}
int parseCmdArgs(int argc, char** argv)
{
if (argc == 1)
{
printUsage();
return -1;
}
for (int i = 1; i < argc; ++i)
{
if (string(argv[i]) == "--help" || string(argv[i]) == "/?")
{
printUsage();
return -1;
}
else if (string(argv[i]) == "--try_use_gpu")
{
if (string(argv[i + 1]) == "no")
try_use_gpu = false;
else if (string(argv[i + 1]) == "yes")
try_use_gpu = true;
else
{
cout << "Bad --try_use_gpu flag value\n";
return -1;
}
i++;
}
else if (string(argv[i]) == "--output")
{
result_name = argv[i + 1];
i++;
}
else
{
Mat img = imread(argv[i]);
if (img.empty())
{
cout << "Can't read image '" << argv[i] << "'\n";
return -1;
}
imgs.push_back(img);
}
}
return 0;
}
Edit : I just tried running the sample code from the samples folder itself and it works. The makefile runs perfectly without any error if I place it in the opencv/samples/cpp folder , but doesn't when I copy - paste it to another location.
The error means that the linker can't find your main function. Even though stitch.cpp defines main (I assume), the linker can't find it. The reason is unclear, because of the way you constructed your Makefile. I would make these changes:
use CXXFLAGS and/or CPPFLAGS for C++, because CFLAGS is for C.
expand the pkg-config output in make, so you can see what your compiler is being asked to do.
Your Makefile would then look like this:
CXXFLAGS = $(shell pkg-config --cflags opencv)
LIBS = $(shell pkg-config --libs opencv)
% : %.cpp
g++ $(CXXFLAGS) -o $# $^ $(LIBS)
I would like to think that with these changes the actual source of the problem will become apparent.
The following program illustrates the issue:
Makefile:
CFLAGS = -O3 -std=c++0x
LDFLAGS = -lreadline
test: test.o
g++ $(CFLAGS) $< $(LDFLAGS) -o $#
test.o: test.cpp Makefile
g++ $(CFLAGS) -c $<
test.cpp:
#include <fnmatch.h>
#include <readline/readline.h>
#include <stdlib.h>
#include <stdio.h>
#include <time.h>
static double time()
{
timespec ts;
clock_gettime(CLOCK_REALTIME, &ts);
return ts.tv_sec + (1e-9 * (double)ts.tv_nsec);
}
static void time_fnmatch()
{
for (int i = 0; i < 2; i++)
{
double t = time();
for (int i = 0; i < 1000000; i++)
{
fnmatch("*.o", "testfile", FNM_PERIOD);
}
fprintf(stderr, "%f\n", time()-t);
}
}
int main()
{
time_fnmatch();
char *input = readline("> ");
free(input);
time_fnmatch();
}
Output:
0.045371
0.044537
>
0.185246
0.181607
Before calling readline(), the fnmatch calls are about 4x faster. Although
this performance difference is worrying, I'm most interested in finding out
what exactly the readline() call might be doing to the program state that
would have this effect on other library calls.
Just a guess: readline initialization probably calls setlocale.
When a program starts up, it is in the C locale; a call to setlocale(LC_ALL, "") will enable the default locale, and these days, the default locale usually uses UTF-8, in which case many string operations become more complex. (Even just iterating over a string.)