LinuxQuestions.org
Share your knowledge at the LQ Wiki.
Home Forums Tutorials Articles Register
Go Back   LinuxQuestions.org > Forums > Non-*NIX Forums > Programming
User Name
Password
Programming This forum is for all programming questions.
The question does not have to be directly related to Linux and any language is fair game.

Notices


Reply
  Search this Thread
Old 03-20-2006, 12:46 PM   #1
ta0kira
Senior Member
 
Registered: Sep 2004
Distribution: FreeBSD 9.1, Kubuntu 12.10
Posts: 3,078

Rep: Reputation: Disabled
Forcing extern declaration symbol generation in shared library


I am creating a shared library which is dependent on several implementation-defined functions; they are delared 'extern' within 'extern "C"' in the shared library and are called from within certain library functions. The implementation binary is linked to the shared library using ld, at which time the shared library will have access to the implementation function:
Code:
//Shared Library

extern "C"
{
extern void ImplFunc();
}

void LibFunc()
{
ImplFunc();
}
Code:
//Implementation

void ImplFunc() {}

int main()
{
LibFunc();
}
The problem is that when using 'extern "C"', some 'extern' symbols are not generated, and therefore the implementation link fails. I've even tried to declare the extern functions '__attribute__ ((used))', but that does not work either.

I had a similar problem with global variables not being generated; they were not used by the shared lib, but were meant to be available to the implementation. I could fix this by declaring them 'extern' prior to their definition, however:
Code:
extern const int Value;
const int Value = 0;
Am I doing something wrong? Thanks.
ta0kira
 
Old 03-20-2006, 02:59 PM   #2
bluelightning
Member
 
Registered: Mar 2006
Location: Redmond, WA
Distribution: FC4, WinXP Pro
Posts: 37

Rep: Reputation: 15
Let me make sure I understand what you're doing. You have a shared library that exports some functions and imports some other functions, and the executable that links to it is supposed to provide the implementation for the functions the library needs? Instead, could you put the functions that the shared library imports into a second library?

I'm not sure whether you care, but that will not port to Windows. I recommend using function pointers instead.
 
Old 03-21-2006, 12:22 PM   #3
ta0kira
Senior Member
 
Registered: Sep 2004
Distribution: FreeBSD 9.1, Kubuntu 12.10
Posts: 3,078

Original Poster
Rep: Reputation: Disabled
You understand correctly (well, the way I worded my post anyway); I have a basic lib which exports a single function, but its processing depends on numerous imported functions. The imported functions fall into a few specific categories; each category has a separate shared lib which is not linked to the base lib directly (that way individual components are upgradable.) The main binary (which uses the exported function from the basic lib) is then linked with the basic lib plus one of each of the component libs. This provides the basic lib's functionality to the binary using the functionality of the chosen component libs. This way the binary is very small (<16k), and can therefore be quickly relinked with different component libs as needed.

Without 'extern "C"', all of the imported (i.e. 'extern') function symbols required are generated. I would rather not use function pointers because I want ld and dl to take care of the dirty work between shared libs. Additionally, everything could be linked into a single massive binary if necessary, which would easily port to Windows. I really don't need C generated symbols; it links fine generated in C++. I really only want them in C so I can --retain-symbols-file them so someone can nm and see what functions are needed. In this particular case, I am not taking Windows into account. Thanks.
ta0kira
 
Old 03-21-2006, 10:25 PM   #4
bluelightning
Member
 
Registered: Mar 2006
Location: Redmond, WA
Distribution: FC4, WinXP Pro
Posts: 37

Rep: Reputation: 15
I didn't know the answer to this, but it seemed like something interesting, so I gave it a try and got it to work. It looks like extern "C" only switches the calling convention to C-style, and does not declare functions as extern. The extern "C" is needed both when declaring the function for import and when exporting it.

I made a test app on FC4 with g++ (GCC) 4.0.2 20051125 (Red Hat 4.0.2-8).

First I made library.cpp:
Code:
//Shared Library
#include <iostream>
using namespace std;

extern "C"
{
        extern void ImplFunc();
}

void LibFunc()
{
        cout << "Inside LibFunc. v1" << endl;
        ImplFunc();
}
I compiled this with the following command:
g++ -shared library.cpp -o library.so

Next I created a cpp for your implementation, main.cpp:
Code:
//Implementation
#include <iostream>
using namespace std;

extern void LibFunc();

extern "C"
{
        void ImplFunc()
        {
                cout << "Implementation's ImplFunc called" << endl;
        }
}

int main()
{
        cout << "Calling LibFunc" << endl;
        LibFunc();
        cout << "LibFunc done" << endl;
}
I compiled it with this command:
g++ library.so main.cpp -o main

So I wouldn't have to install library.so somewhere, I changed my library path:
export LD_LIBRARY_PATH=.

When I run main, I get:
Code:
Calling LibFunc
Inside LibFunc. v1
Implementation's ImplFunc called
LibFunc done
To be sure that library.so isn't statically linked with main, I changed the "v1" to "v2" in library.cpp, and recompiled *just* library.so. Here is the new output from main:
Code:
Calling LibFunc
Inside LibFunc. v2
Implementation's ImplFunc called
LibFunc done
 
Old 03-22-2006, 12:43 PM   #5
ta0kira
Senior Member
 
Registered: Sep 2004
Distribution: FreeBSD 9.1, Kubuntu 12.10
Posts: 3,078

Original Poster
Rep: Reputation: Disabled
Thanks, I'll try using 'extern "C"' in both places. I still can't get some of the symbols to be generated (as far as the global symbol table) in the shared library, however:
Code:
main.cpp
//Shared lib

extern "C"
{
        extern void ImplFunc();
        extern void LibFunc();
}

void LibFunc()
{ ImplFunc(); }
Code:
symbols

ImplFunc
LibFunc
Code:
> g++ main.cpp -fPIC -c -o main.o
> ld --retain-symbols-file=symbols -shared main.o -o libmain.so
> nm libmain.so
       U ImplFunc
xxxxxx T LibFunc
The nm output should something like the above, however certain symbol names aren't being retained.
ta0kira

Last edited by ta0kira; 03-26-2006 at 03:49 PM.
 
Old 03-22-2006, 11:13 PM   #6
bluelightning
Member
 
Registered: Mar 2006
Location: Redmond, WA
Distribution: FC4, WinXP Pro
Posts: 37

Rep: Reputation: 15
I'm not following. I tried the code you posted. I do get output like what you described. How is that output incorrect? If you want the rest of the symbols, don't filter them out with a symbols file.
 
Old 03-26-2006, 03:49 PM   #7
ta0kira
Senior Member
 
Registered: Sep 2004
Distribution: FreeBSD 9.1, Kubuntu 12.10
Posts: 3,078

Original Poster
Rep: Reputation: Disabled
I was giving that example to elaborate on the context of the problem. The actual shared lib I am compiling is around 40 files and 10k lines, so I can't reproduce the problem in a simple example. What is happening with my lib is the equivalent of the 'ImplFunc' symbol not being generated by the call to g++ for the .o file; it's as if the compiler thinks that it hasn't been used anywhere, and therefore does not generate it. I'm trying to find a way to force gcc to generate an apparently unused 'extern "C"' declaration for the .o file so it can be linked into the lib.
ta0kira
 
  


Reply



Posting Rules
You may not post new threads
You may not post replies
You may not post attachments
You may not edit your posts

BB code is On
Smilies are On
[IMG] code is Off
HTML code is Off



Similar Threads
Thread Thread Starter Forum Replies Last Post
Linking to a static library gives unresolved symbol enemorales Programming 3 01-24-2006 08:19 AM
undefined symbol in the shared object phani@tcs Linux - General 3 01-10-2006 03:51 PM
howto compile bin with my library using all-static and shared linked standart library stpg Programming 4 06-29-2004 04:20 AM
How do I custom write a library and use it in the header declaration ? Linh Programming 4 05-26-2004 03:38 PM
problem with extern file pointer in library linuxping Programming 5 02-08-2004 09:55 PM

LinuxQuestions.org > Forums > Non-*NIX Forums > Programming

All times are GMT -5. The time now is 02:51 AM.

Main Menu
Advertisement
My LQ
Write for LQ
LinuxQuestions.org is looking for people interested in writing Editorials, Articles, Reviews, and more. If you'd like to contribute content, let us know.
Main Menu
Syndicate
RSS1  Latest Threads
RSS1  LQ News
Twitter: @linuxquestions
Open Source Consulting | Domain Registration