I have this code:
#include <stdio.h>
#include <pthread.h>
void* cuoco(void* arg)
{
fprintf(stderr,"Inizio codice cuoco\n");
fprintf(stderr,"Fine codice cuoco\n");
return NULL;
}
void* cameriere(void* arg)
{
fprintf(stderr,"Inizio codice cameriere\n");
fprintf(stderr,"Fine codice cameriere\n");
return NULL;
}
void* cliente(void* arg)
{
fprintf(stderr,"Inizio codice cliente\n");
fprintf(stderr,"Fine codice cliente\n");
return NULL;
}
int main(int argc, char* argv[])
{
void* (*routine)(void*);
routine=cuoco;
pthread_t thread_cuoco,thread_cameriere,thread_cliente;
pthread_create(&thread_cuoco,NULL,routine,NULL);
return 0;
}
And in the compiler options I insert -lpthread
But it says:
"Undefined reference to pthread_create"
I use ubuntu 10.10, so I already have pthread library installed, I can't figure the reason of this error.
Use -lpthread as the last compiler flag.
example:
gcc -o sample sample.c -lpthread
Without seeing the compiler command, I suspect -lpthread is not at end. Libraries need to be placed at end of the compiler command:
gcc main.c -lpthread
However, use -pthread instead of -lpthread, as -pthread may add other settings (like defining the macro _REENTRANT for example).
Use the following command:
gcc -pthread -o main main.c
In Eclipse, you should add string pthread.
Project -> Properties -> C/C++ Build -> Settings -> Tool Settings -> GCC Linker -> Libraries -> Libraries (-l) -> Add -> pthread
After this, you can Build your project.
found the solution guys :D
just go to settings >> compiler >> linker tab >>add lib
go to drive and go to lib folder and find x86_64_linux_gnu and find pthread
enjoy :)
Related
In C using GCC, one can use the following function to have some code called upon loading a shared library:
static void __attribute__((constructor)) _my_initializer(void)
{
...
}
After some search on the web, I could not find the equivalent in Fortran using GCC (i.e. gfortran). For sure that this feature must exist in gfortran since it comes from GCC (thus it should be available in all languages supported by GCC). Any pointers?
"For sure that this feature must exist in gfortran since it comes from GCC" That is clearly false. It simply does not have to exist. gfortran does support the !GCC$ ATTRIBUTES directive, but the number of attributes supported is limited.
You can write your constructor in C and let it be part of the same library and call any Fortran code you want.
Example:
library.f90:
subroutine sub() bind(C)
write(*,*) "Hello!"
end subroutine
init_library.c:
void sub(void);
static void __attribute__((constructor)) _init(void)
{
sub();
}
load_library.c:
#include <stdio.h>
#include <unistd.h>
#include <dlfcn.h>
typedef void (*foo)(void);
int main(int argc, char* argv[])
{
void *lib = dlopen("library.so", RTLD_NOW);
if(lib == NULL)
return printf("ERROR: Cannot load library\n");
dlclose(lib);
}
compile and run:
> gfortran -c -fPIC init_library.c
> gfortran -c -fPIC library.f90
> gfortran -shared library.o init_library.o -o library.so
> gfortran load_library.c -ldl
> ./a.out
Hello!
I'm trying to call a "core" function from a shared library's function but I get:
./a.out: symbol lookup error: ./libtest.so: undefined symbol: testf
The code I'm using is very basic because I'm just getting into writing shared libraries and it's just for testing purposes:
main.h
extern void testf();
main.c
#include <stdio.h>
#include <dlfcn.h>
extern void testf()
{
printf("bla bla\n");
}
int main () {
void *handle = NULL;
void (*testlib)(void) = NULL;
handle = dlopen("./libtest.so" ,RTLD_LAZY);
testlib = dlsym(handle, "testfunc");
if ( testlib == NULL )
{
printf("Error: %s \n", dlerror());
}
else
{
testlib();
}
}
libtest.c
#include <stdio.h>
#include "main.h"
void testfunc() {
printf("Test plugin\n");
testf();
}
And the commands I compile it with:
gcc -fPIC -g -c -Wall libtest.c
gcc -shared -Wl,-soname,libtest.so.1 -o libtest.so libtest.o -lc
gcc main.c -ldl
Is it possible to achieve this? Tried to find the answer, but don't really know how to form the question right so I can search better for it.
Thanks!
here you are trying to call a function of a executable from the library. I think you actually required reverse of this.
Sorry, managed to find the answer:
I was compiling the main program with wrong parameters, should use:
gcc main.c -ldl -rdynamic
I want to access the global variable of executable in shared library? I have tried to compile using option -export-dynamic but no luck.
I have tried with extern key word. this also not working.
Any help or suggestion would be appreciable.
Environment c - Linux
executable:-
tst.c
int tstVar = 5;
void main(){
funInso();
printf("tstVar %d", tstVar);
}
lib:-
tstLib.c
extern int tstVar;
void funInso(){
tstVar = 50;
}
Since my code is very big, I just gave the sample which I have used in my program.
It should work. BTW, your tst.cis lacking a #include <stdio.h>. And its main should return an ìnt and end with e.g. return 0;.
With
/* file tst.c */
#include <stdio.h>
int tstVar = 5;
extern void funInso(void);
int main(){
funInso();
printf("tstVar %d\n", tstVar);
return 0;
}
and
/* file tstlib.c */
extern int tstVar;
void funInso(){
tstVar = 50;
}
I compiled with gcc -Wall -c tst.c the first file, I compiled with gcc -Wall -c tstlib.c the second file. I made it a library with
ar r libtst.a tstlib.o
ranlib libtst.a
Then I linked the first file to the library with gcc -Wall tst.o -L. -ltst -o tst
The common practice is to have with your library a header file tstlib.h which would contain e.g.
#ifndef TSTLIB_H_
#define TSTLIB_H_
/* a useful explanation about tstVar. */
extern int tstVar;
/* the role of funInso. */
extern void funInso(void);
#endif /*TSTLIB_H */
and have both tst.c and tstlib.c contain an #include "tstlib.h"
If the library is shared, you should
compile the library file in position independent code mode
gcc -Wall -fpic -c tstlib.c -o tstlib.pic.o
link the library with -shared
gcc -shared tstlib.pic.o -o libtst.so
Note that you can link a shared object with other libraries. You could have appended -lgdbm to that command, if your tstlib.c is e.g. calling gdbm_open hence including <gdbm.h>. This is one of the many features shared libraries give you that static libraries don't.
link the executable with -rdynamic
gcc -rdynamic tst.o -L. -ltst -o tst
Please take time to read the Program Library Howto
your tstVar variable could be defined in the lib. and you can share this variable via functions:
setFunction: to edit this variable
void setFunction (int v)
{
tstVar = v;
}
getFunction: to return the variable
int getFunction ()
{
return tstVar
}
In libname.h:
int add_libname(int, int);
In libname.c:
#include "libname.h"
int add_libname(int a, int b)
{
return a+b;
}
I can build the shared library this way:
gcc -shared -fPIC libname.c -o libname.so
But I can't use it in another programe test.c:
#include <stdio.h>
#include "libname.h"
int main(int argc, char* argv[])
{
printf("%d\n", add_libname(1,5));
}
Reporting undefined reference to add_libname when I try to build it..
What's wrong here?
Because add_libname takes (int, int) you're giving it (1+5 = 6) or just (int)
I think you meant
add_libname(1, 5);
Also to compile it correctly you must use gcc like so
gcc -o myapp test.c -L. -lname
the lib part of libname is ignored as it is implicit
To create a shared library use these
gcc -fPIC -c libname.c
it gives warning: position independent code and libname.o file is generated.
and now type these command,
gcc -shared libname.so libname.o
libname.so ( the shared library is created with .so extension). To use the shared library
gcc -I/give the path of libname.h sourcefile.c /give the path of your .so file
example if your c file is file.c and the header file libname.h is in c:\folder1\project and your libname.so (shared library) is in c:\folder\project2
then
gcc -I/cygdrive/c/folder1/project file.c /cygdrive/c/folder/project/libname.so
this is the gcc command to be used while using the shared library.
Thank you.
I am doing some C code on a Solaris SPARC system and am scratching my head at an "inconsistency" I have found in my integration testing.
I am doing some tests into an SAP system and am using the SAP RFCSDK, but SAP is not my question here at all.....I am wondering if I am missing some compile options etc
Let me try explain:
Client code -> Shared lib(custom) -> Shared Lib (SAP) -> SAP === works 100%
Client code -> Shared lib(custom PROXY)-> Shared lib(custom) -> Shared Lib (SAP) -> SAP ==INVALID handle
So without going into too much detail have you ever heard of any "handle" becoming invalid just because another shared lib was "inbetween" the client and "destination shared lib"?
The PROXY shared lib that is causing the issue with the INVALID HANDLE does nothing special, just a "pass through"
#include <stdio.h>
#include <stdlib.h>
#include "saprfc_receiver_proxy.h"
#include "saprfc_receiver.h"
int saprfc_receiver_proxy_initialize(char *sap_hostname, char *sap_client,
int sap_sysnbr, char *sap_language, char *sap_user, char *sap_password,
int sap_rfctrace){
return saprfc_receiver_initialize(sap_hostname, sap_client, sap_sysnbr,
sap_language, sap_user, sap_password, sap_rfctrace);
}
int saprfc_receiver_proxy_beginTransaction(char *tid){
return saprfc_receiver_beginTransaction(tid);
}
int saprfc_receiver_proxy_commitTransaction(char *tid){
return saprfc_receiver_commitTransaction(tid);
}
int saprfc_receiver_proxy_rollbackTransaction(char *tid){
return saprfc_receiver_rollbackTransaction(tid);
}
int saprfc_receiver_proxy_writeMessage(char *tid, char *buffer){
return saprfc_receiver_writeMessage(tid, buffer);
}
int saprfc_receiver_proxy_openConnection(){
return saprfc_receiver_openConnection();
}
int saprfc_receiver_proxy_closeConnection(){
return saprfc_receiver_closeConnection();
}
The compilation is very straightforward, here is the shared lib compile that calls the SAP shared libs directly:
/usr/sfw/bin/gcc -m64 -R/usr/sfw/lib/64 -c -fPIC -I../include \
-I../rfcsdk/include saprfc_receiver.c -o saprfc_receiver.o
/usr/sfw/bin/gcc -m64 -R/usr/sfw/lib/64 -shared -L../rfcsdk/lib/ \
-o libsaprfc_receiver.so saprfc_receiver.o -lrfccm -lrfc
And here is the proxy shared lib compile:
/usr/sfw/bin/gcc -m64 -R/usr/sfw/lib/64 -c -fPIC -I../include \
saprfc_receiver_proxy.c -o saprfc_receiver_proxy.o
/usr/sfw/bin/gcc -m64 -R/usr/sfw/lib/64 -shared -L../lib \
-o libsaprfc_receiver_proxy.so saprfc_receiver_proxy.o -lsaprfc_receiver
So is there any "golden rule" when using C to make sure that "shared libs in between" do not influence the state at all?
Sorry if my explaining is bad, I will try edit this post later with more detail....
The bottom line is that if the client calls the shared lib (custom) directly then it works, the moment I add a SIMPLE proxy in between the SAP handle goes bad.