Link to home
Start Free TrialLog in
Avatar of GauravN4U
GauravN4U

asked on

C code linking



hi people
I was trying to compile a code using some
user defined shared libraries.
the name of the library he has kept is as

---------------------------------------------------
g++ -lsemphore -L./fifoimplementation semcreate.c

->undefined reference to sem_open(const char *, int. ...)
->undefined referenc to sem_close(sem_t *)

---------------------------------------------------

directory : ./fifoimplementation
***** libsemaphore.so.1,  
      libsemaphore.so -> libsemaphore.so.1

---------------------------------------------------


I used nm command on libsemaphore.so.1
(which is placed in ./fifoimplementation directory)
and it says "sem_close" and "sem_open" declared
with a T (normal) status.

I used gcc -c sem_open.c [to produce the sem_open.o file]
 gcc -c sem_close.c [to produce the sem_close.o file]
 gcc -shared -o libsemaphore.so.1 *.o [to produce
         the .so file]


below are the .c files .. u can cut these and try to
compile the library and use it
---------------------------------------------------

 

 


********************
/*semcreate.c - uses sem_open and sem_close :*/

#include <stdio.h>
#include <unistd.h>
#include <stdlib.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>

#include "./fifoimplementation/semaphore.h"

int
main(int argc, char **argv)
{
 int  c, flags;
 sem_t *sem;
 unsigned int value;

 flags = O_RDWR | O_CREAT;
 value = 1;
 while ( (c = getopt(argc, argv, "ei:")) != -1) {
  switch (c) {
  case 'e':
   flags |= O_EXCL;
   break;

  case 'i':
   value = atoi(optarg);
   break;
  }
 }
 if (optind != argc - 1)
  {printf("usage: semcreate [ -e ] [ -i initalvalue ] <name>");
  exit(0);}

 sem = sem_open(argv[optind], flags, S_IRWXU | S_IROTH | S_IRGRP, value);

 sem_close(sem);
 exit(0);
}
******************************


------------------------------------
when I try to compile it with
g++ -lsemaphore -L./fifoimplementation semcreate.c
is says undefined reference to sem_open and sem_close.
but they are there in the library and also in the header
file included.
-----------------------------------------

 

 

****************************
/*semaphore.h*/
 
typedef struct {
 int sem_fd[2];  /*2 fd's for reading and writing from the FIFO*/
 int sem_magic;  /*magic no*/
} sem_t;


#define SEM_MAGIC 0x92843

#ifdef SEM_FAILED
#undef SEM_FAILED
#define SEM_FAILED ((sem_t *) (-1)) /*this aviods compiler warnings ... I dont know*/
#endif


sem_t * sem_open(const char *, int, ...);
int sem_close(sem_t *);
int sem_wait(sem_t *);
int sem_post(sem_t *);
int sem_unlink(const char *);
***********************

 

 

*********************
/*sem_open.c
opening a semaphore in FIFO implementation
sem_open(const char *pathname, int oflags, ...)
if the O_CREAT flag is there in oflags we need
the rest of the two arguments namely int mode, int value*/

#include <stdio.h>
#include <unistd.h>
#include <stdarg.h>
#include <stdlib.h>
#include <fcntl.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <errno.h>


sem_t *sem_open(const char *pathname, int oflags, ...)
{

int save_errno;
va_list ap;
mode_t mode;  /*mode of the file : O_RDWR, O_RDONLY etc*/
unsigned int value;
sem_t *sem;
int flags;
char c;
int i;

if (oflags & O_CREAT ==0) /*we are creating the semaphore */
 {
 va_start(ap, oflags);
 mode = va_arg(ap, mode_t);
 value = va_arg(ap, unsigned int);
 va_end(ap);

 if (mkfifo(pathname, mode)<0) /*the FIFO is created*/
 
if ( (errno ==EEXIST) && (oflags & O_EXCL)==0) /*file already exists and we have not set the O_EXEL flag*/
   oflags = ~O_CREAT;  /* we dont want to write the value of the semaphore */
                                   /*in the fifo as it is already there*/
  else
   return ((sem_t *) -1);
 }
 
 

/*allocate memory to the sem_t structure*/
sem = (sem_t *) malloc(sizeof(sem_t));

/*fifo created*/
( sem->sem_fd[0] = open(pathname, O_RDONLY | O_NONBLOCK) <0)  /*an opening of the FIFO will block if */
 goto error;       /*i.e unlink the fifo created the other end hasen't opened it */
         /*we specify O_NONBLOCK to avoid the deadlock */
         /*and then turn off the O_NONBLOCK option */
         /*to wait for the semaphore values see fifo(4)*/
           

if (sem->sem_fd[1] = open(pathname, O_WRONLY | O_NONBLOCK) <0)
 goto error;

flags = fcntl(sem->sem_fd[0], F_GETFL);     /*get the current flags fot this file*/
flags &= ~O_NONBLOCK;                          /*reset O_NONBLOCK*/
fcntl(sem->sem_fd[0], F_SETFL, flags);       /*reset the flags*/

 

if (oflags & O_CREAT)        /*first time ... initialize the semaphore*/
 {
 for (i=0;i<value;i++)           /*write #value bytes to the fifo to init it*/
  if (write(sem->sem_fd[1], &c, 1)<0)
   goto error;
 }

sem->sem_magic = SEM_MAGIC;
return (sem);

error:
 save_errno = errno;      /*save errno lest it should get modified */
 if (oflags & O_CREAT ) unlink(pathname);
 close(sem->sem_fd[0]);     /*in this call*/
 close(sem->sem_fd[1]);
 free((void *) sem);
 errno = save_errno;      /*restore it*/
 return ((sem_t *) (-1));


}
********************

 

***********************
/*sem_close.c*/
#include <errno.h>
#include <malloc.h>
#include <stdio.h>
#include <unistd.h>


int sem_close(sem_t *sem)
{

if (sem->sem_magic != SEM_MAGIC)
 {
 errno = EINVAL;
 return (-1);
 }

sem->sem_magic = 0;  /*reset the magic number ... semaphore is now closed*/

if ( close(sem->sem_fd[0] ==-1 ) || close(sem->sem_fd[1] == -1) )
 {
 free(sem);
 return (-1);
 }

free(sem);
return (0);
}

*********************

 

 


-----------------------------------------------------------
if anybody can tell me the commands of how to
make libraries and also how to use the built in libraries,
I will be highly obliged !!!!!!!

Thankzzz
Gaurav.
-------------------------------------------------------------

 

Avatar of bryanh
bryanh

Simple.  You're using gcc to create the library and g++ to link with it.  gcc and g++ use different translations between source code variables and object code symbols.  Since I don't see any non-C code in sem_create.c, just change g++ ... sem_create.c to gcc ... sem_create.c and it should work.
Avatar of GauravN4U

ASKER

plzzzzzz cut and copy this code and try to compile this
I have tried using both g++ and gcc. the mannual says g++ is a front eng for gcc !!
Sorry, that's way too much work for me.  But if you'd like to email the files to me at bryanh@giraffe-data.com, I'll give it a try.

Also, instead of posting your entire program, you should have cut it down to the smallest example that still demonstrates the problem.  That would be about 10 lines in two files.  That would make it easier for people to cut and paste it and also to see the problem.
okieee
actually I just want to know how to build our own libraries and use them, in C.
I was able to make the .so files with the sem_open, and sem_close functions. but when I try to use them I get an error saying undefined reference .....



sorry about the sphagatti above but they are just 3 files.
But can't u just copy them into the files .... I have tried my level best to make it clear !!
Gaurav.

P.S: I am a newbie and am doing this stuff for the first time
You seem to know how to build your own libraries and use them in C.  Except for using g++ where you're supposed to use gcc, you're doing the same thing I do successfully.

But you said you get the same result if you use gcc.  I'd like to see some proof of that, like a session transcript like the one above, only with gcc instead of g++.  g++ is incapable of generating the error messages you get from g++.

g++, by the way, is a front end for gcc, but it invokes gcc with options that make it behave differently than ordinary gcc.

I'm 99% certain that your programs would build just fine for me.  Since there's so little chance of me learning anything by it, I don't want to go to the trouble of extracting them from the web page.  I don't know of any tools on my system to copy a large quantity of text from a web page into three files without a whole bunch of steps and tedious scrolling and mousing.  It's not something I normally do.  On the other hand, if you sent them to me as MIME attachments in email, it would only take a few quick keystrokes to put them in my home directory and run them through the compiler, so it might be worth the time.
okay, I tried your code and it build OK.  
1.  
i compiled with both gcc and g++ and  a combination of both, IT works.
I had to modify /*fifo created*/
( sem->sem_fd[0] = open(pathname, O_RDONLY | O_NONBLOCK) <0)  /*an opening of the FIFO will block if
*/
I could be a typo, but you were missing an "if"
2.
 I got rid of the hard coded include "./fifosutff" -- try Not to do that in the future, and configure directories using your  makefile
3.
[g&beavis]#g++ -c semaphore.c
[g&beavis]#ar -cr libSemaphore.a semaphore.o
[g&beavis]#g++ -c semcreate.c
[g&beavis]#g++ -L./ -lSemaphore semcreate.o -o SemaApps
works like a charm

PS.  using "goto" is NOT recommened at all.  try NOT to use it "a reason to be fired :-)"
there are better ways to catch errors "exception handling"

oh, yeah, I removed prototype from header file and put it in semcreate.c as extern, should not matter either way.
well well well .. I tried it too .... and it worked !
dammn I dont know what was wrong !
Thankzz
just one more thing ...
sem_open and other posix functions are also there in linux
in libpthread.so
but the posix sem_open function dosent work !!
when I do nm on libpthread
sem_open is marked with a T which means it is a normal implementation , still i can't seem to get it working
can u try to compile the semcreate.c with the posix implementations ??
any comments ??  Bryanh ??
Thankzz
ASKER CERTIFIED SOLUTION
Avatar of bryanh
bryanh

Link to home
membership
This solution is only available to members.
To access this solution, you must be a member of Experts Exchange.
Start Free Trial
well it compiles fine when linked with the libpthread.so.
but dosen't do the job.
I think the distro is not 100% posix compliant !!
I am using red hat 7.0 !
what do u say ??

Anywayzzz Thankzzz for the help.
It is highly appericiated.
Gaurav.


look under /etc/include for pthread.h it must be there.
look under /lib for libthread.so and it should be there.  RH7.0 distribution is complete, the gcc compiler is funky though, VERY VERY VERY funky, be careful. there are plenty problem with their compiler, and it is NOT a standard release from gcc.  check with gcc -v and if you get 2.96 to to www.gnu.org and download latest stable release of gcc and install it, build it, same difference. linking with -lpthread should work find though.
Hi garoba,
I had included pthread.h
and linked it with libpthread.so which was in /usr/lib
but sem_open function dosent seem to work
all the other functions sem_init sem_post etc
work fine ( if I use a memory based semaphore [sem_init])
So I think it is not there
Even the mannual page is not there for sem_open
but it is there for sem_init and etcs.
Thankzzzzzzz For Help
Much Appericiated
Gaurav
did you ever do a  "man sem_open"  try it and it will learn more.
yup garboua I did man sem_open and the page wont open.
But when I did "man sem_init" it shows me those functions ... except sem_opsn so I thought it isint supported. I am using Red HAt 7.0 system.