views:

1159

answers:

3

EDIT: I suppose I should clarify, in case it matters. I am on a AIX Unix box, so I am using VAC compilers - no gnu compilers. End edit


I am pretty rusty in C/C++, so forgive me if this is a simple question.

I would like to take common functions out of a few of my C programs and put them in shared libraries or shared objects. If I was doing this in perl I would put my subs in a perl module and use that module when needed.

For the sake of an example, let's say I have this function:

int giveInteger()
{
    return 1034;
}

Obviously this is not a real world example, but if I wanted to share that function, how would I proceed?

I'm pretty sure I have 2 options:

  1. Put my shared function in a file, and have it compile with my main program at compile time. If I ever make changes to my shared function, I would have to recompile my main program.
  2. Put my shared function in a file, and compile it as a shared library (if I have my terms correct), and have my main program link to that shared library. Any changes I make to my shared library (after compiling it) would be integrated into my main program at runtime without re-compiling my main program.

Am I correct on that thinking?

If so, how can I complish either/both of those methods? I've searched a lot and I seem to find information how how I could have my own program link to someone else's shared library, but not how to create my own shared functions and compile them in a way I can use them in my own program.

Thanks so much!

Brian


EDIT:

Conclusion

Thanks everyone for your help! I thought I would add to this post what is working for me (for dynamic shared libraries on AIX) so that others can benefit:

I compile my shared functions:

xlc -c sharedFunctions.c -o sharedFunctions.o

Then make it a shared object:

xlc -qmkshrobj -qexpfile=exportlist sharedFunctions.o
xlc -G -o libsharedFunctions.so sharedFunctions.o  -bE:exportlist

Then link it another program:

xlc -brtl -o mainProgram mainProgram.c  -L. -lsharedFunctions

And another comment helped me find this link, which also helped: http://publib.boulder.ibm.com/infocenter/comphelp/v7v91/topic/com.ibm.vacpp7a.doc/proguide/ref/compile_library.htm

Thanks again to all who helped me out!

+2  A: 

You've got a third option. In general, your C++ compiler should be able to link C routines. The necessary options may vary from compiler to compiler, so R your fine M, but basically, you should be able to compile with g++ as here:

$ g++ -o myapp myapp.cpp myfunc.c giveint.c

... or compile separately

$ gcc -c myfunc.c
$ gcc -c giveint.c
$ g++ -c myapp.cpp
$ g++ -o myapp myapp.o myfunc.o

You also need to include your declaration of the functions; you do that in C++ as

extern "C" {
    int myfunc(int,int);
    int giveInterger(void);
}
Charlie Martin
Often .h files even for c include the extern "C" bit in an #ifdef __CPP__ just for this cases.
BCS
Thanks Charlie - I don't have gcc, so I'm not sure if that makes a difference - I just edited my post to state I have VAC compilers...
BrianH
The command line is a bit different, but not much. There's no difference in the idea.
Fred Larson
yeah some test whether __cplusplus is defined and put extern "C" around its declarations. c++ compilers have to define it. but some other libraries do not.
Johannes Schaub - litb
Max Lybbert
I don't have access to AIX (nor have I used it in like 10 years) but I'm sure all the flag you need are there. Just read the man page. The core point is to compile to a .o and link if you don't want to build a library. (Which I wouldn't bother with unless it was used in > 2 places.)
Charlie Martin
+3  A: 

Yeah you are correct. The first is called a static library, while the second is called a shared library, because the code is not bound to the executable at compile time, but everytime again when your program is loaded.

Static library

Compile your library's code as follows:

gcc -c *.c

The -c tells the program not to link the object file, but just leaves you with object files for each .c file that was compiled. Now, archive them into one static library:

ar rcs libmystuff.a *.o

man ar will tell you what the rcs options mean. Now, libmystuff.a is a archive file (you can open it with some zip-file viewers) which contain those object files, together with an index of symbols for each object file. You can link it to your program:

gcc *.c libmystuff.a -o myprogram

Now, your program is ready. Note that the order of where the static libraries appear in the command matter. See my Link order answer.

Shared library

For a shared library, you will create your library with

gcc -shared -o libmystuff.so *.c

That's all it takes, libmystuff.so is now a shared object file. If you want to link a program to it, you have to put it into a directory that is listed in the /etc/ld.so.conf file, or that is given by the -L switch to GCC, or listed in the LD_LIBRARY_PATH variable. When linking, you cut the lib prefix and .so suffix from the library name you tell gcc.

gcc -L. -lmystuff *.c -o myprogram

Internally, gcc will just pass your arguments to the GNU linker. You can see what arguments it pass using the -### option: Gcc will print the exact arguments given to each sub process.

For details about the linking process (how some stuff is done internally), view my Linux GCC linker answer.

Johannes Schaub - litb
And the AIX compiler switch for a shared library is documented at http://publib.boulder.ibm.com/infocenter/comphelp/v7v91/index.jsp?topic=/com.ibm.vacpp7a.doc/compiler/ref/ruoptpic.htm .
Max Lybbert
Thanks for the AIX link - it led me to this page, which really helps: http://publib.boulder.ibm.com/infocenter/comphelp/v7v91/index.jsp?topic=/com.ibm.vacpp7a.doc/proguide/ref/compile_library.htm
BrianH
A: 

You need to distinguish between recompiling and relinking.

If you put giveInteger() into a separate (archive) library, and then modify it later, you'll (obviously) need to recompile the source file in which it is defined, and relink all programs that use it; but you will not need to recompile such programs [1].

For a shared library, you'll need to recompile and relink the library; but you will not have to relink or recompile any of the programs which use it.

Building C++ shared libraries on AIX used to be complicated; you needed to use makeC++SharedLib shell script. But with VAC 5.0 and 6.0 it became quite easy. I believe all you need to do is [2]:

xlC -G -o shr.o giveInteger.cc
xlC -o myapp main.cc shr.o

[1] If you write correct Makefile (which is recommended practice), all of this will happen automatically when you type make.

[2] There is a certain feature of AIX which may complicate matters: by default shared libraries are loaded into memory, and "stick" there until subsequent reboot. So you may rebuild the shr.o, rerun the program, and observe "old" version of the library being executed. To prevent this, a common practice is to make shr.o world-unreadable:

chmod 0750 shr.o
Employed Russian