Symbian3/SDK/Source/GUID-006C503D-1E52-450D-A4DA-8C19B141E09F.dita
changeset 7 51a74ef9ed63
child 8 ae94777fff8f
equal deleted inserted replaced
6:43e37759235e 7:51a74ef9ed63
       
     1 <?xml version="1.0" encoding="utf-8"?>
       
     2 <!-- Copyright (c) 2007-2010 Nokia Corporation and/or its subsidiary(-ies) All rights reserved. -->
       
     3 <!-- This component and the accompanying materials are made available under the terms of the License 
       
     4 "Eclipse Public License v1.0" which accompanies this distribution, 
       
     5 and is available at the URL "http://www.eclipse.org/legal/epl-v10.html". -->
       
     6 <!-- Initial Contributors:
       
     7     Nokia Corporation - initial contribution.
       
     8 Contributors: 
       
     9 -->
       
    10 <!DOCTYPE concept
       
    11   PUBLIC "-//OASIS//DTD DITA Concept//EN" "concept.dtd">
       
    12 <concept id="GUID-006C503D-1E52-450D-A4DA-8C19B141E09F" xml:lang="en"><title>Introduction
       
    13 to Intermixing C and C++</title><shortdesc>When porting an open source application or any C (or C++) applications
       
    14 on top of Symbian/S60 using P.I.P.S., the developer will come across situations
       
    15 where C and C++ (and Symbian C++ as well) codes will be used together. The
       
    16 open source community implements a vast number of libraries that export C
       
    17 APIs to the user of such libraries.</shortdesc><prolog><metadata><keywords/></metadata></prolog><conbody>
       
    18 <section id="GUID-88635D46-AEF6-4E8E-969D-D3E56941F289-GENID-1-8-1-11-1-1-5-1-3-1-7-1-4-1-4-1-3-1">       <title>When
       
    19 and why to use C linkage</title>       <p>While porting such applications,
       
    20 if developers have to intermix C and C++ code, they then have to depend on
       
    21 C++ language features like extern "C" for giving C linkage to some set of
       
    22 APIs. This is required because C and C++ compilers handle function prototype
       
    23 in a different way. C++ compilers use name mangling, (or name decoration)
       
    24 to generate unique names for identifiers in a program. It is because of this
       
    25 technique, in C++, that it is possible to overload any functions (this requires
       
    26 that all the overloaded functions should have a different argument list).
       
    27 The C++ mangled name for any identifier contains all the necessary information
       
    28 that may be needed by the linker, such as linkage type, scope, calling convention,
       
    29 and others.</p><p>All identifiers (function names or variable names) declared
       
    30 or defined in C++ source or headers are subject to name mangling. When it
       
    31 comes to C, however, there is nothing called name mangling or overloading.
       
    32 It applies when the developer tries to use C APIs by including corresponding
       
    33 headers. To avoid name mangling, the developer should mention explicitly that
       
    34 those APIs are C APIs, by using the extern "C" keyword.  </p>     </section>
       
    35 <section id="GUID-88635D46-AEF6-4E8E-969D-D3E56941F289-GENID-1-8-1-11-1-1-5-1-3-1-7-1-4-1-4-1-3-2">       <title>Syntax
       
    36 of extern C</title>       <p>The syntax of extern "C" is shown below: </p><codeblock xml:space="preserve">extern "C" declaration ;
       
    37 </codeblock><p>The declaration (or definition) that immediately follows extern
       
    38 "C" has the C linkage. </p><codeblock xml:space="preserve">extern "C" { 
       
    39    declaration ; 
       
    40    declaration ; 
       
    41    ... 
       
    42 }</codeblock><p>Everything between the curly braces has C linkage, unless
       
    43 declared otherwise. </p>     </section>
       
    44 <section id="GUID-88635D46-AEF6-4E8E-969D-D3E56941F289-GENID-1-8-1-11-1-1-5-1-3-1-7-1-4-1-4-1-3-3">       <title>How
       
    45 to use extern C</title>       <p>While writing header files with C functions
       
    46 which will be included by both C and C++ source files, the user must use extern
       
    47 "C" properly. See the example below: </p><codeblock xml:space="preserve">/*File: GoodCHeader.h */
       
    48 /* Can be used by C/C++ header and source files directly */
       
    49 
       
    50 #ifdef __cplusplus
       
    51 extern "C" {
       
    52 #endif
       
    53 /* Write C function declarations here */
       
    54 void Function1(int, int);
       
    55 char* Function3(char*, int);
       
    56 int Function2(int);
       
    57 #ifdef __cplusplus
       
    58 } /* extern "C" */
       
    59 #endif
       
    60 </codeblock><p>Using <codeph>ifdef __cplusplus</codeph> is required since
       
    61 C does not support or recognize the <codeph>extern</codeph> keyword. It is
       
    62 C++ that provides the mechanisms for mixing C and C++ codes in the same program.
       
    63 To be precise, C++ supports mixing codes that are compiled by C and C++ compatible
       
    64 compilers in the same program.</p><p>If the C header is already defined and
       
    65 it does not have all the APIs defined under extern "C", then while including
       
    66 such a header in C++ source or header files, extern "C" should be used as
       
    67 in the example below:  </p><codeblock xml:space="preserve">*File: PureCHeader.h */
       
    68 /* If C++ header/source files need to include this header, extern "C" should be used*/
       
    69 /* Define all C APIs here*/
       
    70 void Function1(int, int);
       
    71 char* Function3(char*, int);
       
    72 int Function2(int);
       
    73 #endif
       
    74 
       
    75 
       
    76 //File: CSource.cpp
       
    77 // C++ source file using PureCHeader.h
       
    78 extern "C" {
       
    79 #include "PureCHeader.h"
       
    80 }
       
    81 void Foo() {
       
    82    // use those C APIs here
       
    83    int ret = Function2(10);
       
    84 }
       
    85 </codeblock>     </section>
       
    86 <section id="GUID-88635D46-AEF6-4E8E-969D-D3E56941F289-GENID-1-8-1-11-1-1-5-1-3-1-7-1-4-1-4-1-3-4">       <title>Mixing
       
    87 C and C++ features using extern "C"</title>       <p>The developer
       
    88 can use all the features of C++ except templates within C by giving those
       
    89 functions extern "C" linkage. See the example below:</p><codeblock xml:space="preserve">#include &lt;iostream&gt;
       
    90 using namespace std;
       
    91 
       
    92 extern "C" {
       
    93 
       
    94 //Can give C linkage to this class!!
       
    95 class Sample{
       
    96 public:
       
    97    Sample(int a = 10) : iMem(a) { }
       
    98    void Display() { cout&lt;&lt;"iMem is : "&lt;&lt;iMemend1; }
       
    99 private:
       
   100    int iMem;
       
   101 };
       
   102 
       
   103 /*
       
   104 //Can not  give C linkage to template!!
       
   105 //If we uncomment this code, then it will give a compilation error.
       
   106 template&lt;class DataType&gt; void Foo(DataType data) {
       
   107 }*/
       
   108 }</codeblock>     </section>
       
   109 <section id="GUID-9AC33F43-5B75-4994-899F-02CD3CE43E5C"><title>Extending C
       
   110 codes with C++ Codes</title><p>Using C linkage, C codes like structures and
       
   111 functions that manipulate those structures can be extended efficiently in
       
   112 a C++ source file as in the example below:  </p><codeblock xml:space="preserve">/* File: CHeader.h */
       
   113 typedef struct{
       
   114    char* name;
       
   115    int id;
       
   116    float price;
       
   117 } Item;
       
   118 
       
   119 int Push(Item* item);
       
   120 int Pop(Item* item);
       
   121 
       
   122 
       
   123 
       
   124 /* File: CppHeader.h */
       
   125 //Give external linkage to C structure
       
   126 extern "C" {
       
   127 # include "CHeader.h"
       
   128 }
       
   129 
       
   130 class MyStack : public Item {
       
   131 public:
       
   132    MyStack(char* aName, int aId, float aPrice) : name(aName), id(aId), price(aPrice) { }
       
   133    int PushOnToStack() { return Push(this);}
       
   134    int PopFromStack() { return Pop(this); }
       
   135 };
       
   136 </codeblock></section>
       
   137 </conbody></concept>