Variable Scope ?

2

2DevOrNot2Dev

Hi there,

I'm not sure if this is a C question or a compiler specific question.
However since the issue seems to be occuring on all compilers I try it
on I think it may be a language question.
Anyways to the point...

I have 2 seperate sources

main.c and module.c

main is our main application and module.c compiles to a dynamically
linked library
main has a circular buffer defined in the global scope, this is
intended to be a sort of scratchpad for communication between main and
module.

The problem I am having occurs at runtime. When I run the
application, the library cannot find the circular buffer created by
main.

I'm not sure it's relevant but here is the code...

module.c
extern circular_buffer service_result_buffer;

main.c
circular_buffer service_result_buffer;

Again like I said, I just can't see any reason that module can't see
the buffer in main, any help would be appreciated.

Thanks in advance!
 
N

Nate Eldredge

2DevOrNot2Dev said:
Hi there,

I'm not sure if this is a C question or a compiler specific question.
However since the issue seems to be occuring on all compilers I try it
on I think it may be a language question.
Anyways to the point...

I have 2 seperate sources

main.c and module.c

main is our main application and module.c compiles to a dynamically
linked library
main has a circular buffer defined in the global scope, this is
intended to be a sort of scratchpad for communication between main and
module.

The problem I am having occurs at runtime. When I run the
application, the library cannot find the circular buffer created by
main.

I'm not sure it's relevant but here is the code...

module.c
extern circular_buffer service_result_buffer;

main.c
circular_buffer service_result_buffer;

I think this is a compiler issue. The sort of code you're using looks
correct, and a similar example compiles and runs on my system, with the
module linked either statically or dynamically. You should probably ask
about this in a forum specific to your compiler or operating system.
When you do, it will probably be helpful if you can include:

- a very simple and complete example that exhibits your problem. E.g. a
module containing a function that increments an `int' defined in the
main program.

- the precise commands and options you use to compile, link and run the
example program, and the exact error message that you get.

- the name and version of your compiler and operating system.
 
2

2DevOrNot2Dev

I think this is a compiler issue.  The sort of code you're using looks
correct, and a similar example compiles and runs on my system, with the
module linked either statically or dynamically.  You should probably ask
about this in a forum specific to your compiler or operating system.
When you do, it will probably be helpful if you can include:

- a very simple and complete example that exhibits your problem.  E.g. a
  module containing a function that increments an `int' defined in the
  main program.

- the precise commands and options you use to compile, link and run the
  example program, and the exact error message that you get.

- the name and version of your compiler and operating system.

Here is an example of what I'm working with...

common.h
typedef struct circular_buffer
{
char * buf;

}circular_buffer;

module.c
#include <stdio.h>
#include "common.h"

extern circular_buffer buffer;

int show_buff()
{
printf("%s",buffer.buf);

}

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

circular_buffer buffer;

int main(int argc, char* argv[])
{
void * plugin_handle;
int (* print_func)();
buffer.buf = "Hello World!";
char * errstr;

plugin_handle = dlopen("module.so",RTLD_NOW|RTLD_GLOBAL);
if(plugin_handle)
{
print_func = (int (*)())dlsym
(plugin_handle,"show_buff");
if(print_func)
{
print_func();
}else{
errstr = dlerror();
printf("%s\n",errstr);
}
}else{
printf("%s\n",dlerror());
}

}

the compile is as follows...

gcc -shared -g module.c -o module.so
gcc -g -ldl main.c -o test

Here is the complete output of gcc -v in case that helps...
Reading specs from /usr/lib/gcc-lib/i586-suse-linux/3.3.3/specs
Configured with: ../configure --enable-threads=posix --prefix=/usr --
with-local-prefix=/usr/local --infodir=/usr/share/info --mandir=/usr/
share/man --enable-languages=c,c++,f77,objc,java,ada --disable-
checking --libdir=/usr/lib --enable-libgcj --with-gxx-include-dir=/
usr/
include/g++ --with-slibdir=/lib --with-system-zlib --enable-shared --
enable-__cxa_atexit i586-suse-linux
Thread model: posix
gcc version 3.3.3 (SuSE Linux)

And here is the output of ./test
/test/module.so: undefined symbol: buffer

Again any help would be greatly appreciated.

Thanks in advance!
 
N

Nate Eldredge

[Crossposted and followups to comp.os.linux.development.apps]

2DevOrNot2Dev said:
Here is an example of what I'm working with...

common.h
typedef struct circular_buffer
{
char * buf;

}circular_buffer;

module.c
#include <stdio.h>
#include "common.h"

extern circular_buffer buffer;

int show_buff()
{
printf("%s",buffer.buf);

}

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

circular_buffer buffer;

int main(int argc, char* argv[])
{
void * plugin_handle;
int (* print_func)();
buffer.buf = "Hello World!";
char * errstr;

plugin_handle = dlopen("module.so",RTLD_NOW|RTLD_GLOBAL);
if(plugin_handle)
{
print_func = (int (*)())dlsym
(plugin_handle,"show_buff");
if(print_func)
{
print_func();
}else{
errstr = dlerror();
printf("%s\n",errstr);
}
}else{
printf("%s\n",dlerror());
}

}

the compile is as follows...

gcc -shared -g module.c -o module.so
gcc -g -ldl main.c -o test

Here is the complete output of gcc -v in case that helps...
Reading specs from /usr/lib/gcc-lib/i586-suse-linux/3.3.3/specs
Configured with: ../configure --enable-threads=posix --prefix=/usr --
with-local-prefix=/usr/local --infodir=/usr/share/info --mandir=/usr/
share/man --enable-languages=c,c++,f77,objc,java,ada --disable-
checking --libdir=/usr/lib --enable-libgcj --with-gxx-include-dir=/
usr/
include/g++ --with-slibdir=/lib --with-system-zlib --enable-shared --
enable-__cxa_atexit i586-suse-linux
Thread model: posix
gcc version 3.3.3 (SuSE Linux)

And here is the output of ./test
/test/module.so: undefined symbol: buffer

Again any help would be greatly appreciated.

Ah, you're loading the module with dlopen. In that case you'll need to
use the '-rdynamic' option when linking the executable 'test' in order
for the module to be able to see the executable's symbols.

Also, you will need to use the '-fPIC' option when compiling module.c.

So a complete compilation might look like:

gcc -c -g -fPIC module.c
gcc -g -shared -fPIC -o module.so module.o
gcc -c -g main.c
gcc -o test -g -rdynamic main.o -ldl

Finally, you might need to pass dlopen a path, such as "./module.so" or
"/absolute/path/module.so", or else set the LD_LIBRARY_PATH environment
variable appropriately.

See if that works.
 
R

Richard Bos

2DevOrNot2Dev said:
The problem I am having occurs at runtime. When I run the
application, the library cannot find the circular buffer created by
main.

I'm not sure it's relevant but here is the code...

module.c
extern circular_buffer service_result_buffer;

main.c
circular_buffer service_result_buffer;

Again like I said, I just can't see any reason that module can't see
the buffer in main, any help would be appreciated.

We'd need to see real, compilable code that demonstrates the problem,
and exact error messages, to make sure, but under some implementations
this could depend on the order in which these modules are linked in.
If so, the solution will depend on which toolchain you're using, and
you'll be better off asking in a compiler- or OS-specific newsgroup, if
only because there may well be a better, but implementation-dependent,
way to achieve your goals.

Richard
 
S

Stephen Sprunk

2DevOrNot2Dev said:
I'm not sure if this is a C question or a compiler specific question.
However since the issue seems to be occuring on all compilers I try it
on I think it may be a language question.
Anyways to the point...

I have 2 seperate sources

main.c and module.c

main is our main application and module.c compiles to a dynamically
linked library
main has a circular buffer defined in the global scope, this is
intended to be a sort of scratchpad for communication between main and
module.

The problem I am having occurs at runtime. When I run the
application, the library cannot find the circular buffer created by
main.

It sounds like your implementation doesn't provide a way for a dynamic
library to resolve symbols in the executable that loaded it -- or if it
does, you're not linking it correctly.

Aside from Nate's solution, which I assume is correct, I'd point out
that a common solution to this general problem is for the library to
have some sort of initialization function, and you would pass the
address of your shared "scratch" space to the library when calling it.
This will work regardless of how the linking is done.

S
 
2

2DevOrNot2Dev

It sounds like your implementation doesn't provide a way for a dynamic
library to resolve symbols in the executable that loaded it -- or if it
does, you're not linking it correctly.

Aside from Nate's solution, which I assume is correct, I'd point out
that a common solution to this general problem is for the library to
have some sort of initialization function, and you would pass the
address of your shared "scratch" space to the library when calling it.
This will work regardless of how the linking is done.

S

Right the only problem is that the module is written outside of my
control.
I only have access to the main that uses the module, and the module
expects but does not provide the scratch space.
 
I

Ian Collins

2DevOrNot2Dev said:
Right the only problem is that the module is written outside of my
control.
I only have access to the main that uses the module, and the module
expects but does not provide the scratch space.

If that's the case, you appear to have an issue with your unnamed
platform or tools. Try a more specific forum.
 
C

CBFalconer

2DevOrNot2Dev said:
.... snip ...

Here is an example of what I'm working with...

common.h
typedef struct circular_buffer {
char * buf;
}circular_buffer;

module.c
#include <stdio.h>
#include "common.h"

extern circular_buffer buffer;

int show_buff() {
printf("%s",buffer.buf);
}

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

First obvious error. There is no dlfcn.h in standard C.
#include "common.h"
circular_buffer buffer;

int main(int argc, char* argv[]) {
void * plugin_handle;
int (* print_func)();
^
Second obvious error. From here to ...
buffer.buf = "Hello World!";
char * errstr;

plugin_handle = dlopen("module.so",RTLD_NOW|RTLD_GLOBAL);

Third obvious off-topic error. There is no dlopen() in std C.
Masked by 2nd error.
if(plugin_handle) {
print_func = (int (*)())dlsym
^
.... here is a comment, and ignored by the compiler.
 
C

CBFalconer

CBFalconer said:
... snip ...

Here is an example of what I'm working with...

common.h
typedef struct circular_buffer {
char * buf;
}circular_buffer;

module.c
#include <stdio.h>
#include "common.h"

extern circular_buffer buffer;

int show_buff() {
printf("%s",buffer.buf);
}

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

First obvious error. There is no dlfcn.h in standard C.
#include "common.h"
circular_buffer buffer;

int main(int argc, char* argv[]) {
void * plugin_handle;
int (* print_func)();
^
Second obvious error. From here to ...
buffer.buf = "Hello World!";
char * errstr;

plugin_handle = dlopen("module.so",RTLD_NOW|RTLD_GLOBAL);

Third obvious off-topic error. There is no dlopen() in std C.
Masked by 2nd error.
if(plugin_handle) {
print_func = (int (*)())dlsym
^
... here is a comment, and ignored by the compiler.

Scratch the comments about comments. I had the Pascal bug.
 
K

Kaz Kylheku

And here is the output of ./test
/test/module.so: undefined symbol: buffer

Again any help would be greatly appreciated.

Hi there 2DevOrNot2Dev.

The answer is definitely 2Dev!

Dynamic linking is platform-specific. For instance on Windows, the functions
are LoadLibrary and GetProcAddress, rather than dlopen and dlsym.

The problem could be that you executable has not exported the "buffer" symbol
for dynamic linkage. You didn't use the -rdynamic option when compiling and
linking main, look it up here:

http://gcc.gnu.org/onlinedocs/gcc-4.3.3/gcc/Link-Options.html#Link-Options

If you're not sure if something is in C or not, google for the document "C99
draft". If the library function or syntax is described the document
``ISO/IEC 9899:1999'', it's in C. You can find a draft of this online.

Next look here: http://www.opengroup.org/onlinepubs/009695399/ Single Unix
Specification Issue 6, online. This is a very useful resource. Whatever is in
there is part of the Unix standard. This covers not only C interfaces, but the
shell and utilities uncluding vi and ex. All of the programming interfaces
in there can be regarded as topical in comp.unix.programmer.

If you can't find it in there, or in the C standard (or draft thereof)
it's probably a gcc, glibc or Linux-specific feature, for which
you can hopefully find documentation, or get help in
comp.os.linux.development.apps or comp.os.linux.development.system.

Be wary of some programming man pages that come with some Linux distros; some
of them are very old, dating back to around 1993, and pertaining to an old C
library which is no longer in use. The modern GNU C library is documented
using GNU info: "info libc".
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

Forum statistics

Threads
473,769
Messages
2,569,582
Members
45,066
Latest member
VytoKetoReviews

Latest Threads

Top