Creation Zone

  • Subscribe to our RSS feed.
  • Twitter
  • StumbleUpon
  • Reddit
  • Facebook
  • Digg

Wednesday, 12 January 2005

C/C++: External linkage with extern "C"

Posted on 15:32 by Unknown
[Updated: 04/07/2006] Much accurate information is available in a better format at:
Mixed-Language Programming and External Linkage
__________________

It is a common practice to mix code written in one programming language with 
code written in another. But the developer needs to take some additional care to
make such programs work; else the compilation endup with link errors about unresolved
symbols. Let's discuss the problem(s) & solution(s) of mixing code written in
different programming languages with a simple example

Assume that we're writing C++ code and wish to call a C function from C++ code

bpte4500s001:/sunbuild1/giri/testcases/%cat greet.h
char *greet();

bpte4500s001:/sunbuild1/giri/testcases/%cat greet.c
#include "greet.h"

char *greet()
{
return ((char *) "Hello!");
}

bpte4500s001:/sunbuild1/giri/testcases/%cc -G -o libgreet.so greet.c

bpte4500s001:/sunbuild1/giri/testcases/%ls -l libgreet.so
-rwxrwxr-x 1 build engr 2788 Jan 12 12:21 libgreet.so*

Let's try to call the C function "greet()" from a C++ program

bpte4500s001:/sunbuild1/giri/testcases/%cat mixedcode.cpp
#include

extern char *greet();

int main() {
char *greeting = greet();
cout << greeting << "\n";
return (0);
}

Note:
The "extern" keyword declares a variable or function and specifies that it has
external linkage i.e., its name is visible from files other than the one in which
it's defined

bpte4500s001:/sunbuild1/giri/testcases/%CC -lgreet mixedcode.cpp
Undefined first referenced
symbol in file
char*greet() mixedcode.o
ld: fatal: Symbol referencing errors. No output written to a.out

Though the C++ code is linked with the dynamic library "libgreet.so" which holds the
implementation for greet(), the linking failed with undefined symbol error. What
went wrong?

The reason for the link error is that a typical C++ compiler mangles (encrypts) some
of the symbols (for eg., function name) to support Function Overloading. So the
symbol "greet" will be changed to something else depending on the algorithm
implemented in compiler during symbol mangling process and the object file will not
be having the symbol "greet" anywhere. Symbol table section of mixedcode.o object
file confirms this. Lets have a look at the symbol tables of libgreet.so &
mixedcode.o:

bpte4500s001:/sunbuild1/giri/testcases/%elfdump -s libgreet.so

Symbol Table Section: .symtab
index value size type bind oth ver shndx name
...
[1] 0x00000000 0x00000000 FILE LOCL D 0 ABS libgreet.so
...
[37] 0x00000268 0x00000004 OBJT GLOB D 0 .rodata _lib_version
[38] 0x000102f3 0x00000000 OBJT GLOB D 0 .data1 _edata
[39] 0x00000228 0x00000028 FUNC GLOB D 0 .text greet
[40] 0x0001026c 0x00000000 OBJT GLOB D 0 .dynamic _DYNAMIC

bpte4500s001:/sunbuild1/giri/testcases/%elfdump -s mixedcode.o

Symbol Table Section: .symtab
index value size type bind oth ver shndx name
[0] 0x00000000 0x00000000 NOTY LOCL D 0 UNDEF
[1] 0x00000000 0x00000000 FILE LOCL D 0 ABS mixedcode.cpp
[2] 0x00000000 0x00000000 SECT LOCL D 0 .rodata
[3] 0x00000000 0x00000000 FUNC GLOB D 0 UNDEF
__1cDstd2l6Frn0ANbasic_ostream4Ccn0ALchar_traits4Cc____pkc_2_

[4] 0x00000000 0x00000000 FUNC GLOB D 0 UNDEF __1cFgreet6F_pc_
[5] 0x00000000 0x00000000 NOTY GLOB D 0 UNDEF __1cDstdEcout_
[6] 0x00000010 0x00000050 FUNC GLOB D 0 .text main
[7] 0x00000000 0x00000000 NOTY GLOB D 0 ABS __fsr_init_value

bpte4500s001:/sunbuild1/giri/testcases/%dem __1cFgreet6F_pc_

__1cFgreet6F_pc_ == char*greet()

char*greet() has been mangled to __1cFgreet6F_pc_ by the Sun Studio 9 C++ compiler.
That's why the static linker (ld) couldn't match the symbol in the object file.
What's the solution to this problem?

The solution to this problem is to disable name mangling, so that we can call
external C functions from C++ code. This can be done by prepending extern "C" to the
signature of the function to be called from C++ code.

syntax:
extern "C" <function declaration>

Or if we have more than one C function to be called from C++, put the
function signatures within a extern "C" block

extern "C" {
<function declaration>
<function declaration>
...
<function declaration>
}

The linkage directive extern "C" tells the compiler to inhibit the default encoding
(name mangling) of a function name for a particular function

Notes:
1) A function declared as extern "C" cannot be overloaded
2) extern "C" declaration can only be applied to global functions
3) extern "C" declaration must always be after the last include
4) It is possible to use a linkage directive with all the functions in a file. This
is useful if we wish to use C library functions in a C++ program

extern "C" {
#include "mylibrary.h"
}

Please do not use extern "C" when including standard C header files because these
header files already contain extern "C" directives

So let's modify the source of mixedcode.cpp a bit, and recompile the program

bpte4500s001:/sunbuild1/giri/testcases/%cat mixedcode.cpp
#include

extern "C" char *greet();

int main() {
char *greeting = greet();
cout << greeting << "\n";
return (0);
}

bpte4500s001:/sunbuild1/giri/testcases/%CC -lgreet mixedcode.cpp
bpte4500s001:/sunbuild1/giri/testcases/%./a.out
Hello!

It works!! Let's have a look at the symbol table of mixedcode.o again

bpte4500s001:/sunbuild1/giri/testcases/%CC -c -lgreet mixedcode.cpp
bpte4500s001:/sunbuild1/giri/testcases/%elfdump -s mixedcode.o

Symbol Table Section: .symtab
index value size type bind oth ver shndx name
[0] 0x00000000 0x00000000 NOTY LOCL D 0 UNDEF
[1] 0x00000000 0x00000000 FILE LOCL D 0 ABS mixedcode.cpp
[2] 0x00000000 0x00000000 SECT LOCL D 0 .rodata
[3] 0x00000000 0x00000000 FUNC GLOB D 0 UNDEF
__1cDstd2l6Frn0ANbasic_ostream4Ccn0ALchar_traits4Cc____pkc_2_

[4] 0x00000000 0x00000000 FUNC GLOB D 0 UNDEF greet
[5] 0x00000000 0x00000000 NOTY GLOB D 0 UNDEF __1cDstdEcout_
[6] 0x00000010 0x00000050 FUNC GLOB D 0 .text main
[7] 0x00000000 0x00000000 NOTY GLOB D 0 ABS __fsr_init_value

As expected, the function name "greet" was not mangled by the C++ compiler and hence
the linker could find the symbol in the object file and able to build the executable

Please note that extern "C" declaration do not specify the details of what must be
done to allow C & C++ to be mixed. Name mangling is commonly part of the problem to
be solved, but it is only a part. There are certain other issues with mixing
languages and needs additional steps to resolve those issues. For example, on some
systems, C & C++ functions are called in different ways. If the declaration and
definition don't match, the program may crash or show abnormal behavior. For a broad
description, other issues/solutions etc., please read "Linkage Specification" of "The
C++ Programming Language"

Suggested Reading:
1) "Linkage Specification" of "The C++ Programming Language"
2) C++ name mangling - http://technopark02.blogspot.com/2004/11/c-name-mangling.html
Email ThisBlogThis!Share to XShare to Facebook
Posted in | No comments
Newer Post Older Post Home

0 comments:

Post a Comment

Subscribe to: Post Comments (Atom)

Popular Posts

  • *nix: Workaround to cannot find zipfile directory in one of file.zip or file.zip.zip ..
    Symptom: You are trying to extract the archived files off of a huge (any file with size > 2 GB or 4GB, depending on the OS) ZIP file with...
  • C/C++: Printing Stack Trace with printstack() on Solaris
    libc on Solaris 9 and later, provides a useful function called printstack , to print a symbolic stack trace to the specified file descripto...
  • JDS: Installing Sun Java Desktop System 2.0
    This document will guide you through the process of installing JDS 2.0 on a PC from integrated CDROM images Requirements I...
  • Binary compatibility
    What's It? "Binary compatibility" (BC) is the ability of one machine to run software that was written for another without hav...
  • Solaris: NULL pointer bugs & /usr/lib/0@0.so.1 library
    Some programmers assume that a NULL character pointer is the same as a pointer to a NULL string. However de-referencing a NULL pointer (ie.,...
  • Database: Oracle Server Architecture (overview)
    Oracle server consists of the following core components: 1) database(s) & 2) instance(s) 1) database consists of: 1) datafil...
  • Sun: OpenJDK
    Open source JDK, that is. Sun Microsystems did it again -- As promised during JavaOne event back in May 2006, Sun made the implementation of...
  • Consolidating Siebel CRM 8.0 on a Single Sun SPARC Enterprise Server, T5440
    .. blueprint document is now available on wikis.sun.com . Here is the direct link to the blueprint:              Consolidating Oracle Siebel...
  • Oracle Internet Directory 11g Benchmark on SPARC T5
    SUMMARY System Under Test (SUT)     Oracle's SPARC T5-2 server Software     Oracle Internet Directory 11 g R1-PS6 Target Load     50...
  • Fix to Firefox 3 Crash on Solaris 10 x86
    Symptom : Firefox 3 crashes on Solaris 10 x86 when the web browser tries to render some of the HTML pages with SWF content in them. For exam...

Categories

  • 80s music playlist
  • bandwidth iperf network solaris
  • best
  • black friday
  • breakdown database groups locality oracle pmap sga solaris
  • buy
  • deal
  • ebiz ebs hrms oracle payroll
  • emca oracle rdbms database ORA-01034
  • friday
  • Garmin
  • generic+discussion software installer
  • GPS
  • how-to solaris mmap
  • impdp ora-01089 oracle rdbms solaris tips upgrade workarounds zombie
  • Magellan
  • music
  • Navigation
  • OATS Oracle
  • Oracle Business+Intelligence Analytics Solaris SPARC T4
  • oracle database flashback FDA
  • Oracle Database RDBMS Redo Flash+Storage
  • oracle database solaris
  • oracle database solaris resource manager virtualization consolidation
  • Oracle EBS E-Business+Suite SPARC SuperCluster Optimized+Solution
  • Oracle EBS E-Business+Suite Workaround Tip
  • oracle lob bfile blob securefile rdbms database tips performance clob
  • oracle obiee analytics presentation+services
  • Oracle OID LDAP ADS
  • Oracle OID LDAP SPARC T5 T5-2 Benchmark
  • oracle pls-00201 dbms_system
  • oracle siebel CRM SCBroker load+balancing
  • Oracle Siebel Sun SPARC T4 Benchmark
  • Oracle Siebel Sun SPARC T5 Benchmark T5-2
  • Oracle Solaris
  • Oracle Solaris Database RDBMS Redo Flash F40 AWR
  • oracle solaris rpc statd RPC troubleshooting
  • oracle solaris svm solaris+volume+manager
  • Oracle Solaris Tips
  • oracle+solaris
  • RDC
  • sale
  • Smartphone Samsung Galaxy S2 Phone+Shutter Tip Android ICS
  • solaris oracle database fmw weblogic java dfw
  • SuperCluster Oracle Database RDBMS RAC Solaris Zones
  • tee
  • thanksgiving sale
  • tips
  • TomTom
  • windows

Blog Archive

  • ►  2013 (16)
    • ►  December (3)
    • ►  November (2)
    • ►  October (1)
    • ►  September (1)
    • ►  August (1)
    • ►  July (1)
    • ►  June (1)
    • ►  May (1)
    • ►  April (1)
    • ►  March (1)
    • ►  February (2)
    • ►  January (1)
  • ►  2012 (14)
    • ►  December (1)
    • ►  November (1)
    • ►  October (1)
    • ►  September (1)
    • ►  August (1)
    • ►  July (1)
    • ►  June (2)
    • ►  May (1)
    • ►  April (1)
    • ►  March (1)
    • ►  February (1)
    • ►  January (2)
  • ►  2011 (15)
    • ►  December (2)
    • ►  November (1)
    • ►  October (2)
    • ►  September (1)
    • ►  August (2)
    • ►  July (1)
    • ►  May (2)
    • ►  April (1)
    • ►  March (1)
    • ►  February (1)
    • ►  January (1)
  • ►  2010 (19)
    • ►  December (3)
    • ►  November (1)
    • ►  October (2)
    • ►  September (1)
    • ►  August (1)
    • ►  July (1)
    • ►  June (1)
    • ►  May (5)
    • ►  April (1)
    • ►  March (1)
    • ►  February (1)
    • ►  January (1)
  • ►  2009 (25)
    • ►  December (1)
    • ►  November (2)
    • ►  October (1)
    • ►  September (1)
    • ►  August (2)
    • ►  July (2)
    • ►  June (1)
    • ►  May (2)
    • ►  April (3)
    • ►  March (1)
    • ►  February (5)
    • ►  January (4)
  • ►  2008 (34)
    • ►  December (2)
    • ►  November (2)
    • ►  October (2)
    • ►  September (1)
    • ►  August (4)
    • ►  July (2)
    • ►  June (3)
    • ►  May (3)
    • ►  April (2)
    • ►  March (5)
    • ►  February (4)
    • ►  January (4)
  • ►  2007 (33)
    • ►  December (2)
    • ►  November (4)
    • ►  October (2)
    • ►  September (5)
    • ►  August (3)
    • ►  June (2)
    • ►  May (3)
    • ►  April (5)
    • ►  March (3)
    • ►  February (1)
    • ►  January (3)
  • ►  2006 (40)
    • ►  December (2)
    • ►  November (6)
    • ►  October (2)
    • ►  September (2)
    • ►  August (1)
    • ►  July (2)
    • ►  June (2)
    • ►  May (4)
    • ►  April (5)
    • ►  March (5)
    • ►  February (3)
    • ►  January (6)
  • ▼  2005 (72)
    • ►  December (5)
    • ►  November (2)
    • ►  October (6)
    • ►  September (5)
    • ►  August (5)
    • ►  July (10)
    • ►  June (8)
    • ►  May (9)
    • ►  April (6)
    • ►  March (6)
    • ►  February (5)
    • ▼  January (5)
      • C/C++: External linkage with extern "C"
      • Life cycle of a C/C++ program
      • 2s complement
      • Binary compatibility
      • Solaris: Tips
  • ►  2004 (36)
    • ►  December (1)
    • ►  November (5)
    • ►  October (12)
    • ►  September (18)
Powered by Blogger.

About Me

Unknown
View my complete profile