views:

113

answers:

1

I'm trying to dynamically link a module into my program. If I normally compile and link this module then the symbols in it are normally accessible to the C++ via declaring the function prototypes as extern "C". The module itself is a group of fortran functions, that call C++ functions that I have written.

When attempting to dynamically link the module using dlopen and dlsym it fails at the dlopen stage stating that there is an undefined symbol in the module. And I suppose there is, it's just defined in the main program. How do I make the program check for the function within it's local code, and not just die when it can't find it in the imported module.

Thanks.

I hope this isn't too fuzzily asked.

Update: I had the idea that perhaps they need to be declared "extern". So I added a C++ file that declares the functions in that module that its missing as extern "C", so I hope that'd make it look "elsewhere" for them. However it's now complaining that it's lacking functions such as _gfortran_concat_string (when I run dlopen). I imagine this is due to the same problem, but my extern solution doesn't work when I didn't create the functions, and I assume they are built in fortran ones. Any suggestions?

Update 2: Okay so after a brief respite from the problem I've returned and have just attempted simple static linking with the library file that I've created. Unfortunately that doesn't work either, so I'll attempt to explain how I've gone from a working structure to a non-working one and hopefully someone will be able to point out my mistake.

So I had one library that contains 5 source files (and two headers). 2 of these source files are the ones that I want to break away from the library as these functions are user provided (hence why I want to dynamically link them). The makefile looks as such:

pkglib_LTLIBRARIES              = libLibrary.la

libLibrary_la_SOURCES = File1.C \
                File2.C \
                File3.f90 \
                        File4.f \
                        File5.f90

localinc_HEADERS      = Header1.H \
                Header2.H

This is how my makefile structure is working. I didn't put it together and don't really know how it works which isn't incredibly helpful I know, but hopefully you can tell what it's doing. So I created a new folder and split away File4.f and File5.f90, such that I was left with:

pkglib_LTLIBRARIES              = libLibraryOne.la

libLibraryOne_la_SOURCES = File1.C \
                File2.C \
                File3.f90

localinc_HEADERS      = Header1.H \
                Header2.H

and

pkglib_LTLIBRARIES              = libLibraryTwo.la

libLibraryTwo_la_SOURCES = File4.f \
                           File5.f90

These both compile separately but once the program tries to run it is unable to resolve symbols that are present in the other library. Of course that suggests the question "have I linked them together properly" and to that I'll say, I think so, but is there a way I can check? Something of an analogue to running nm to see what symbols are present in a library, but some other program that will tell you what libraries are linked together.

Oh and I'm not sure if I said it but the functions worked perfectly well when the files were all in the same library so they're all declared extern "C", it's just when they're split up into two is the problem.

Thanks!

A: 

The first thing that comes to mind is that it can't find the symbol because its name is mangled in the main binary. Did you definitely define the function as extern "C" within your C++ application? If you didn't, it won't have the proper name and the shared object will be unable to find it.

Alternately, are you able to just link the dynamic library normally rather than using dlopen? That would allow the linker to figure out all the symbols at link time.

Finally are you sure that the version of the .so being opened is the one you think it is? It might be grabbing some other version in a different directory.

Mark B
Upon reading this I've attempted to do some slightly more basic things. Mainly attempting to get static linking working. Unfortunately this does not work either so the problem is clearly with my basic understanding of linking!I doubt I'll be able to fit much explanation in here so I'll edit the main post.
VolatileStorm