Link to home
Create AccountLog in
Avatar of fwlrichard
fwlrichard

asked on

Understanding how Shared Object .so work? Solaris 10 x86 Studio 11

Hi,
I'm trying to understand how shared objects work. I found this example http://piyushkansal.wetpaint.com/page/HOWTO+create+Shared+Object(Run+Time)
but I can't seem to make it work.

Error I get is:
# ./a.out
Arithmetic library cant be opened
Segmentation Fault - core dumped

Warnings I get are:
# /export/home/SUNWspro/bin/cc main.c -ldl
"main.c", line 1: warning: invalid white space character in directive
"main.c", line 2: warning: invalid white space character in directive

I'm not sure where the problem is...
Do I have to have gcc or will studio 11 work?
Or is just a settings problem with the compiler like the PATH's set wrong?
If this is just all wrong then can you give me an example of a shared object that does work with solaris 10 and studio 11?

Thanks
Richard

main.c
#include <stdio.h>
#include <dlfcn.h>

typedef int (*func)(int, int);
func add, sub, mul, div;

int main()
{
int a = 5, b = 4;
void *arithHandle = NULL;

arithHandle = dlopen("libarithmetic.so", RTLD_NOW);
if ( NULL == arithHandle )
{
printf("Arithmetic library cant be opened\n");
}

add = (func) dlsym (arithHandle, "add");
sub = (func) dlsym (arithHandle, "sub");
mul = (func) dlsym (arithHandle, "mul");
div = (func) dlsym (arithHandle, "div");

printf("Add :: %d\n", add(a, b));
printf("Sub :: %d\n", sub(a, b));
printf("Mul :: %d\n", mul(a, b));
printf("Div :: %d\n", div(a, b));

dlclose(arithHandle); //Its important to call dlclose() when you are done
return 0;
}

Open in new window

arithmetic.c
int add(int, int);
int sub(int, int);
int mul(int, int);
int div(int, int);

int add(int a, int b)
{
return a + b;
}

int sub(int a, int b)
{
return a - b;
}

int mul(int a, int b)
{
return a * b;
}

int div(int a, int b)
{
return a / b;
}

Open in new window

arithmetic.h
#ifndef _ARITHMETIC_H_
#define _ARITHMETIC_H_

int add(int, int);
int sub(int, int);
int mul(int, int);
int div(int, int);

#endif

Open in new window

Avatar of phoffric
phoffric

Find out in more detail what your error is using perror.
Likely errors are either permission denied or file cannot be found.
Also, indicate the commands used to compile and then create your .so file.

if ( NULL == arithHandle )  
{
  perror("dlopen");

Open in new window

I took a look at your link. The following worked for me (but I'm on Cygwin) - I changed the .so.1.0.0 extension to .so extension.
Avatar of fwlrichard

ASKER

phoffric,

I changed Line 13 of main.c
arithHandle = dlopen("libarithmetic.so", RTLD_NOW);
arithHandle = dlopen("./libarithmetic.so", RTLD_NOW);
and copied the libarithmetic.so to the RunTime directory
Recompiled ran and got.
#./a.out
Add :: 9
Sub :: 1
Mul :: 20
Div :: 1

So it seems to work now. This makes me think I still have something set wrong like PATH..  


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


For Readers info the commands/steps I used were:
1) Compile to create a ".o" file
# /export/home/SUNWspro/bin/cc -c arithmetic.c

2) Create the dynamic library for load time:
# /export/home/SUNWspro/bin/cc -G -o libarithmetic.so.1.0.0 *.o

3) Create soft links to this library:
# ln -s libarithmetic.so.1.0.0 libarithmetic.so.1
# ln -s libarithmetic.so.1 libarithmetic.so

4) Create the main application:
# /export/home/SUNWspro/bin/cc main.c -ldl

5) Run the application:
# ./a.out

Outputs
Add :: 9
Sub :: 1
Mul :: 20
Div :: 1

Note: For it to work for me I had to change main.c line 13 and copy .so file to the RunTime folder.

Thanks Richard

There seems to be some debate as to wheter setting LD_LIBRARY_PATH to include the .so file will help. But in your link in the OP:
     
j) Let loader know the path of the library, our library "libarithmetic". This step is really important:
export LD_LIBRARY_PATH=..
   

Did you set LD_LIBRARY_PATH
I only skimmed the link. Maybe trying export LD_LIBRARY_PATH=. will help to include the directory from where the executable is run.
export LD_LIBRARY_PATH=..
I use the .. since the executable (in your OP link) was created in a folder below the .so file. Then,
    dlopen("libarithmetic.so", RTLD_NOW);
worked fine.

If you put your main executable in the same folder as your .so file, then
    export LD_LIBRARY_PATH=.
should work.

(Or, alternatively, as you did, you changed the source code to
    dlopen("./libarithmetic.so", RTLD_NOW);

I'll post shortly exactly what my commands were in Cygwin. (I just basically followed your OP link.)
ASKER CERTIFIED SOLUTION
Avatar of phoffric
phoffric

Link to home
membership
Create an account to see this answer
Signing up is free. No credit card required.
Create Account
phoffic,

You are right as many times as I looked at it, I never saw "j)".
j) Let loader know the path of the library, our library "libarithmetic". This step is really important:
export LD_LIBRARY_PATH=..

Thank you
LOL I must first learn to read then reread followed by slowing down and reading... Thanks
LOL, Happy New Year!!
I barely could read it myself after being up so late!