C++ std::thread compilation error on simple thread [duplicate] - c++

I am using pthread.h in a *.cc file. when I try to use pthread_exit(0); or pthread_join(mythrds[yy],NULL); it says:
.cc:(.text+0x3e): undefined reference to `pthread_exit'
when complied very similar code in a *.c file with gcc it work perfect. How Can I use pthread's in c++.. (I also added -lpthread)
..
void *myThreads ( void *ptr )
{
...
pthread_exit(0);
}
..
flags:
g++ -lpthread -Wall -static -W -O9 -funroll-all-loops -finline -ffast-math

You might try using the -pthread option to g++.
-pthread
Adds support for multithreading with the pthreads library. This
option sets flags for both the preprocessor and linker.

Do your pthread header files have extern "C" { ... } around the function prototypes? That's the usual case for the linker not being able to link in C++.
It occurs because C++ generally does name-mangling so that it can encode parameter details into symbols (allowing polymorphism). For example, the functions:
void x(int);
void x(void);
void x(char,int,float,double);
all get different linker symbols.
If the header files don't have the extern "C" { ... }, you may need to do it yourself:
extern "C" {
#include <pthread.h>
}
Hopefully that will work.

Related

C wrapper around C++ library without unnecessary header files

C++ newbie here. I'm creating a C wrapper around C++ library which expose just foo() function.
wrapper.h
#include "SomeLibrary.h"
#include "SomeAnotherLibrary.h"
#ifdef __cplusplus
extern "C" {
#endif
void foo();
#ifdef __cplusplus
}
#endif
wrapper.cpp
#include "wrapper.h"
void foo() {
// calls to `SomeLibrary.h` and `SomeAnotherLibrary.h` functions...
}
I would like to compile this code just to be able to call foo() from a different C code. Note that I care just about the foo() function. I would like to completely ignore SomeLibrary.h and SomeAnotherLibrary.h header files.
So I tried to compilethe wrapper into object file wrapper.o as follows:
g++ -c wrapper.cpp -o wrapper.o -I../some_library/include -I../some_other_library/include -L../some_library/lib -lSomeFirstLibrary -lSomeSecondLibrary
Problem:
When I used wrapper.o in my C project, it still require me to load bunch of header files from SomeLibrary.h and SomeAnotherLibrary.h (which I do not care about at all). Here is my C project code:
my_project.c:
#include "wrapper.h"
void main() {
foo();
}
And compile it:
gcc my_project.c wrapper.o -o my_project
Which yields following error:
my_program.c:3:28: fatal error: SomeLibrary.h: No such file or directory
Question:
How I should compile the wrapper to ignore all other header files except wrapper.h?
Remove
#include "SomeLibrary.h"
#include "SomeAnotherLibrary.h"
from wrapper.h and put those lines in wrapper.cpp next to #include "wrapper.h".
Then remove the -L../some_library/lib -lSomeFirstLibrary -lSomeSecondLibrary linker related flags from the
g++ -c wrapper.cpp -o wrapper.o -I../some_library/include -I../some_other_library/include
command (-c means no linking is done here so there's no point in passing linker flags)
and move it to the
gcc my_project.c wrapper.o -o my_project -L../some_library/lib -lSomeFirstLibrary -lSomeSecondLibrary
command like this.
Then it should work.
When you get undefined reference to... messages, it means that you are declaring functions, and calling them, but never defining them. The error is coming from the fact that you are linking your libraries in the wrong place. You do not need to link libraries to the .o file, you need to link them to the executable file.

`undefined reference` when trying to interface C to call C++

I was trying to call C++ from C. I am not sure about the linking order. It could have been that to cause the error. For some reasons, the compiler complains undefined reference to helloWorld.
Could anyone advise?
main.c:
#include "example.h"
#include <stdio.h>
int main(){
helloWorld();
return 0;
}
example.h:
#ifndef HEADER_FILE
#define HEADER_FILE
#ifdef __cplusplus
extern "C" {
#endif
void helloWorld();
#ifdef __cplusplus
}
#endif
#endif
example.cpp:
#include "example.h"
#include <iostream>
void helloWorld(){
std::cout << "Hello World from CPP";
}
There are two ways to do this. While both work, one is "cleaner" than the other. Side note: As trojanfoe pointed out, you may have left off the .o on the compile/link command.
Here's a two step process:
cc -c main.c
c++ -o mypgm example.cpp main.o
This is a bit ugly because the usual convention is that the source that gets compiled is the one with main
Here's the more usual way:
c++ -c example.cpp
cc -c main.c
c++ -o mypgm main.o example.o
NOTE: In both cases, the "linker" must be c++ to resolve the std::* that example.cpp uses
UPDATE:
What is mypgm?
mypgm [just an example name] is the name of the [fully linked and ready to run] output executable or program. It's the argument for the -o option. The linker takes your relocatable input .o files, links them together to produce the output file [that can now be run as a command].
It's pretty standard nomenclature for something that is arbitrary in example instruction or code sequences [like here on SO]. You could replace "mypgm" with "ursa_majors_test_program" or "example", or whatever you'd like. To run the program, then type ./mypgm [or ./ursa_majors_test_program or ./example]
There's no magic to the name, just like there was no magic to you naming your source files main.c and example.cpp
It should be descriptive of function. If you had said you were working on a text editing program, in my example, I might have used -o editor

Linking C++ static Library in C using gcc

In the following code, I am trying to call a dummy function written in C++ (using C++ header files like ap_fixed.h, ap_int.h) from a C function. The code runs fine when I compile with g++. But when I use gcc for compiling test.c, it throws an error because I have included a C++ header file which is a valid error.
Is there any workaround to compile using gcc? I have read from some posts that it is not a good practice to merge C/C++ code in this manner. Please enlighten me if there are any serious repurcussions of working with a large C codebase and doing similar stuff.
Thanks
Header File: testcplusplus.h
#include "ap_fixed.h"
#include "ap_int.h"
#ifdef __cplusplus
extern "C" {
#endif
void print_cplusplus();
#ifdef __cplusplus
}
#endif
testcplusplus.cc
#include <iostream>
#include "testcplusplus.h"
void print_cplusplus() {
ap_ufixed<10, 5,AP_RND_INF,AP_SAT > Var1 = 22.96875;
std::cout << Var1 << std::endl;
}
test.c
#include <stdio.h>
#include "testcplusplus.h"
int main() {
print_cplusplus();
}
Commands Used:
g++ -c -o testcplusplus.o testcplusplus.cc
ar rvs libtest.a testcplusplus.o
gcc -o test test.c -L. -ltest
Error:
In file included from ap_fixed.h:21:0,
from testcplusplus.h:1,
from test.c:2:
ap_int.h:21:2: error: #error C++ is required to include this header file
The problem here is that the C++ header ap_fixed.h is included from the C program test.c (indirectly via testcplusplus.h).
The solution is to remove the include of headers "ap_fixed.h"
and "ap_int.h" from testcplusplus.h and include them directly from testcplusplus.cpp. The C program doesn't need to know about these anyway, only the C++ wrapper uses them directly.
In a larger example it might be appropriate to split testcplusplus.h into two headers: one that contains only declarations of the external interface you are presenting to the C environment, and another containing the rest - declarations needed internally in the C++ implementation and any required includes.
Once you have done this, you will still face linking errors because the executable that is produced will contain references to symbols from the C++ runtime libraries, plus any other libraries that your C++ code uses. To solve this, add -l directives when compiling the final executable, eg:
gcc -o test test.c -L. -ltest -lstdc++
You do not need to include ap_int.h and ap_fixed.h at this point, as the declaration of the print_cplusplus function does not need those definitions.
Rather, include them in testcplusplus.c, so the C compiler can only see the C compatible interface of the C++ code.

Using dlopen() and dlsym() to get an object out of .so library in C++

I am trying to load a .so file in my Qt application under Linux. That is working using the dlopen() and dlsym() for basic funcions. But I need to get multiple lists of string from the .so library, so I've tried to use a common .h file for both, but I can't access the object from the main app.
This is what I have so far:
extmodule.h
#include <list>
#include <string>
using namespace std;
class ExtModule
{
public:
ExtModule();
list<string> L2MACSource;
list<string> L2MACDest;
...
modulefile.cpp
#include "extmodule.h"
extern "C" ExtModule getCont() {
ExtModule modul;
modul.L2MACSource.push_back("...")
return modul;
}
extern "C" void hello()
{
cout << "hello" << endl;
}
main.cpp
#include "extmodule.h"
...
dlopen("...../modulefile.so", RTLD_LAZY);
...
typedef ExtModule(*loadedFunc)();
loadedFunc ext_get = (loadedFunc)dlsym(ext_mod, "getCont");
typedef void (*hello_t)();
hello_t hello = (hello_t)dlsym(ext_mod, "hello");
hello();
ExtModule modul = ext_get();
hello() function works flawlessly, but I am not able to get the ext_get() working (/external.so: undefined symbol: _ZN9ExtModuleC1Ev). I have to retrieve multiple lists from the .so library, but I don't know if that is the correct way. Also, as you've probably guessed, I am not particularly skilled programmer. Any suggestion will be highly appreciated.
Thank you for any help.
You probably need to compile and link your main program with the -rdynamic flag (to ask the linker to emit dynamic symbols, so that names from the main program are visible to plugins) e.g.
g++ -Wall -rdynamic -g main.cpp -o mainprog
perhaps some libraries and additional flags are missing above, e.g. for Qt
and your plugin with
g++ -Wall -shared -g -fPIC modulefile.cpp -o module.so
perhaps also additional flags are missing above, e.g. for Qt
In practice, Qt knows about plugins and qmake also has plugin support.
If using dlopen & dlsym you always should check for errors:
ext_mod = dlopen("...../modulefile.so", RTLD_LAZY);
if (!ext_mod) {
fprintf(stderr, "dlopen failure: %s\n", dlerror());
exit (EXIT_FAILURE); }
and also
hello_t hello = (hello_t)dlsym(ext_mod, "hello");
if (!hello) {
fprintf(stderr, "dlsym failure: %s\n", dlerror());
exit (EXIT_FAILURE); }
Read dlopen(3), Program Library HowTo, C++ dlopen mini howto, Drepper's paper: How To write Shared Libraries, the Advanced Linux Programming book.
BTW, you don't show all of your C++ code. Please ensure that you have the required constructors and destructors. Read about the rule of three (for old C++03) which becomes the rule of five in C++11.
You can use below command to generate your *.so file.
g++ -shared -fPIC -o {libname}.so -l{name of *.so file where definition of ExtModule} -L{path of module.}

How to link a C++ shared library with gcc

I have seen a GCC link with a C++ shared library, but I am not able to reproduce it on my own. So first I create a C++ library with a testfunction:
g++ -shared -o libtest.so test.c
Then I have a test main function which calls the library function and compile it like this
gcc -o prog.out main.c -L. -ltest
Then i receive the error
undefined reference to 'testfunc'
which i think is caused by different refernce in the library ... C names the function testfunc and C++ names the function [some stuff]__testfunc[maybe again some stuff].
I have also tried to use
gcc -o prog.out main.c -l:libtest.so
but this results in the same error.
Therefore, my question is: How is it possible to link a c++ library with gcc to a c file?
Update: I know i can use extern "C", but that's not the way it is solved. Maybe there are some parameters for the linker instead?
Update2: Just thought it could also be possible that the first part is just compiled with c++ and linked with gcc. Also tried this:
g++ -c testlib.c -o testlib.o
gcc -shared -o libtest.so testlib.o
gcc -o prog.out -l:libtest.so
still doesn't work. Is there something wrong with the flags?
Yes, the problem has nothing to do with shared libraries (I think...) and everything to do with name mangling.
In your header, you must declare the function like this:
#ifdef __cplusplus
extern "C" {
#endif
void testfunc(void);
#ifdef __cplusplus
}
#endif
This will cause testfunc to have the same symbol and calling conventions for both C and C++.
On the system I'm using right now, the C symbol name will be _testfunc and the C++ symbol name (assuming you don't use extern "C") will be __Z8testfuncv, which encodes information about the parameter types so overloading will work correctly. For example, void testfunc(int x) becomes __Z8testfunci, which doesn't collide with __Z8testfuncv.
When you use g++ it compiles ALL source as C++. This means all function use the C++ ABI (this also including name mangling). When you use gcc it compiles *.c files using the C ABI (no name mangling).
Thus the same function compiles with the two different compilers will generate different functions (in a lot of ways). That's because they are different languages.
To force g++ to compile a function using the C ABI prefix it with extern "C"
extern "C" void testfunc(char*);
Alternatively use the block version
extern "C" {
<multiple Functions>
}
To be honest I never compile anything with gcc anymore (unless there is some hard requirement to do so (in which case I usually fix the code so it works in C++)). If you compile all files with g++ just makes the processes simpler.
If you are sure it's not because of name mangling. Then it means gcc could not find the library try giving the full path of the library unless the .so file is in standard location. If you are not sure then recheck for any conflict in variable (function) name. Use namespaces to group classes and define the functions inside the classes to avoid naming conflict