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...
  • 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...
  • Linux: Installing Source RPM (SRPM) package
    RPM stands for RedHat Package Manager. RPM is a system for installing and managing software & most common software package manager used ...
  • Solaris: malloc Vs mtmalloc
    Performance of Single Vs Multi-threaded application Memory allocation performance in single and multithreaded environments is an important a...
  • 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...
  • Installing MySQL 5.0.51b from the Source Code on Sun Solaris
    Building and installing the MySQL server from the source code is relatively very easy when compared to many other OSS applications. At least...
  • Oracle Apps on T2000: ORA-04020 during Autoinvoice
    The goal of this brief blog post is to provide a quick solution to all Sun-Oracle customers who may run into a deadlock when a handful of th...
  • Siebel Connection Broker Load Balancing Algorithm
    Siebel server architecture supports spawning multiple application object manager processes. The Siebel Connection Broker, SCBroker, tries to...
  • 64-bit dbx: internal error: signal SIGBUS (invalid address alignment)
    The other day I was chasing some lock contention issue with a 64-bit application running on Solaris 10 Update 1; and stumbled with an unexpe...
  • Oracle 10gR2/Solaris x64: Fixing ORA-20000: Oracle Text errors
    First, some facts: * Oracle Applications 11.5.10 (aka E-Business Suite 11 i ) database is now supported on Solaris 10 for x86-64 architectur...

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