Symbian3/SDK/Source/GUID-E2B67F14-EC4E-41B6-9F8E-AB58B9E8D7B6.dita
changeset 7 51a74ef9ed63
parent 0 89d6a7a84779
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-E2B67F14-EC4E-41B6-9F8E-AB58B9E8D7B6" xml:lang="en"><title>extern
       
    13 "C" and Symbian DEF files</title><shortdesc/><prolog><metadata><keywords/></metadata></prolog><conbody>
       
    14 <p>This article gives a general idea about the Symbian DEF file. Whenever
       
    15 developers write any DLLs that export a set of APIs to the user, there will
       
    16 be an entry for each exported API in the DEF file created. The developer will
       
    17 use:</p>
       
    18 <ul>
       
    19 <li><p><codeph>IMPORT_C</codeph> while declaring exported APIs</p></li>
       
    20 <li><p><codeph>EXPORT_C</codeph> while defining such APIs</p></li>
       
    21 </ul>
       
    22 <p>After building the application for the first time, it lists all the newly
       
    23 exported APIs. After doing a freeze (for which the <cmdname>abld freeze winscw</cmdname> and <cmdname>abld
       
    24 freeze armv5</cmdname> commands are used), the DEF files will be created under <filepath>BWINS</filepath> and <filepath>EABI</filepath> folders
       
    25 within the project directory. These DEF files are used to create <filepath>.lib</filepath> files
       
    26 for DLLs. In the DEF file, for each exported API, there will be mapping between
       
    27 its prototype and a number will be present.  </p>
       
    28 <p>Let's assume that directory structure used for implementing a library is
       
    29 as shown below:</p>
       
    30 <ul>
       
    31 <li><p><filepath>LibraryName\group</filepath> -- <filepath>bld.inf</filepath> and <filepath>LibraryName.mmp</filepath> (all
       
    32 build-related files)</p></li>
       
    33 <li><p><filepath>LibraryName\inc</filepath> -- All project-specific headers
       
    34 (user include headers)</p></li>
       
    35 <li><p><filepath>LibraryName\src</filepath> -- All project-specific source
       
    36 files </p></li>
       
    37 </ul>
       
    38 <p>If a developer is building the library for the first time, the developer
       
    39 should follow these steps and give the following commands from <filepath>LibraryName\group</filepath>: </p>
       
    40 <ol>
       
    41 <li id="GUID-DE29CFD9-77C2-4790-89C6-5491F3EBA922"><p>Create the <filepath>abld.bat</filepath> file
       
    42 for the project. </p><codeblock xml:space="preserve">LibraryName\group&gt;bldmake bldfiles</codeblock></li>
       
    43 <li id="GUID-DC6AE0F4-64C6-432B-826B-26B7CDA8565C"><p>Build the project for
       
    44 the default platform (which will be <codeph>WINSCW</codeph> and <codeph>ARMV5</codeph>). </p><codeblock xml:space="preserve">LibraryName\group&gt;abld build</codeblock></li>
       
    45 <li id="GUID-836865DB-F613-4000-95AC-DDC9E3F498B2"><p>Create the DEF file
       
    46 for the default platform (<filepath>LibraryName\BWINS\LibraryNameu.def and
       
    47 LibraryName\EABI\LibraryNameu.def</filepath>). </p><codeblock xml:space="preserve">LibraryName\group&gt;abld freeze</codeblock></li>
       
    48 <li id="GUID-C69111BA-1568-4CB4-8AB5-0EDEFC854D39"><p>Create <filepath>.lib</filepath> files
       
    49 for the DLL using DEF file entries. (<filepath>LibraryName.lib</filepath>) </p><codeblock xml:space="preserve">LibraryName\group&gt; abld build</codeblock></li>
       
    50 </ol>
       
    51 <p>The final step is required since applications that link with this library
       
    52 (<filepath>LibraryName.DLL</filepath>) will link with <filepath>LibraryName.lib</filepath> during
       
    53 link time. If the developer fails to perform the final step, the application
       
    54 will get a linker error because there is no <filepath>LibraryName.lib</filepath> present.</p>
       
    55 <section id="GUID-3AD1D783-C36F-4443-8957-6DB9434927B5">       <title>Rule
       
    56 for using extern "C"</title>       <p>When porting or writing libraries that
       
    57 export C APIs to the user, care should be taken to ensure that extern "C"
       
    58 is used properly if those APIs are implemented in a C++ source file. Otherwise
       
    59 these libraries may either not be built for the target platform (ARMV5) or
       
    60 the user of such library will get a linker error when using exported APIs
       
    61 of such library.  </p><p>If extern "C" is declared in the header and not defined
       
    62 in the source, then after building the library there will be a similar entry
       
    63 in DEF files. The compiler will not give external linkage to these APIs. This
       
    64 can be observed when trying to use these APIs from some other C source file.
       
    65 To overcome this, extern "C" must be present in both declarations and definitions.</p><p><b>Example
       
    66 code</b></p><codeblock xml:space="preserve">/*File: SampleDLL.h*/
       
    67 /*extern "C" is not used for declaration!*/ 
       
    68 #ifndef SAMPLEDLL_H
       
    69 #define SAMPLEDLL_H
       
    70 
       
    71 typedef int MyInt;
       
    72 typedef int (*MyFunPtr) ();
       
    73 
       
    74 IMPORT_C int MyLibLibFun1(MyInt aParam);
       
    75 IMPORT_C int MyLibLibFun3(MyFunPtr);
       
    76 IMPORT_C int MyLibLibFun2(int (*MyFun1)());
       
    77 
       
    78 #endif /*SAMPLEDLL_H*/
       
    79 
       
    80 
       
    81 
       
    82 //File: SampleDLL.cpp
       
    83 #include "SampleDLL.h"
       
    84 // extern "C" is used for definition
       
    85 extern "C"  {
       
    86 
       
    87 EXPORT_C int MyLibLibFun1(MyInt aParam)
       
    88    {
       
    89    return aParam + 10;
       
    90    }
       
    91 
       
    92 EXPORT_C int MyLibLibFun2(int (*MyFun1)())
       
    93    {
       
    94    return MyFun1();
       
    95    }
       
    96 
       
    97 EXPORT_C int MyLibLibFun3(MyFunPtr aPtr)
       
    98    {
       
    99    return aPtr();
       
   100    }
       
   101 }
       
   102 </codeblock><p><b>Building for <codeph>WINSCW</codeph></b></p><p>This code
       
   103 will get compiled for <codeph>WINSCW</codeph>. The DEF file for <codeph>WINSCW</codeph> will
       
   104 have the following entries:</p><codeblock xml:space="preserve">EXPORTS
       
   105      ?MyLibLibFun1@@YAHH@Z @ 1 NONAME ; int MyLibLibFun1(int)
       
   106      ?MyLibLibFun2@@YAHP6AHXZ@Z @ 2 NONAME ; int MyLibLibFun2(int (*)(void))
       
   107      ?MyLibLibFun3@@YAHP6AHXZ@Z @ 3 NONAME ; int MyLibLibFun3(int (*)(void)) </codeblock><p>If
       
   108 the user comments extern "C" from the above <filepath>SampleDLL.cpp</filepath> file,
       
   109 the DEF file entries will be the same.</p><p><b>Building for <codeph>ARMv5</codeph></b></p><p>If
       
   110 the user try's the above code without extern "C" in <filepath>SampleDLL.cpp</filepath>,
       
   111 the code will get built and the DEF file entry for <codeph>ARMv5</codeph> will
       
   112 be:</p><codeblock xml:space="preserve">EXPORTS
       
   113      _Z12MyLibLibFun1i @ 1 NONAME
       
   114      _Z12MyLibLibFun2PFivE @ 2 NONAME
       
   115      _Z12MyLibLibFun3PFivE @ 3 NONAME  </codeblock><p>If the user keeps the
       
   116 extern "C" in <filepath>SampleDLL.cpp</filepath>, this code will not get compiled
       
   117 for <codeph>ARMv5</codeph> and will result in the error given below:  </p><codeblock xml:space="preserve">"..\src\Sampledll.cpp", line 7: Error:  #337: linkage specification is incompatible with previous "MyLibLibFun1" (declared at line 9 of "..\inc\SampleDLL.h")
       
   118    EXPORT_C int MyLibLibFun1(MyInt aParam)
       
   119                 ^ 
       
   120 "..\src\Sampledll.cpp", line 17: Error:  #337: linkage specification is incompatible with previous "MyLibLibFun3" (declared at line 11 of "..\inc\SampleDLL.h")
       
   121    EXPORT_C int MyLibLibFun3(MyFunPtr aPtr)
       
   122                ^</codeblock><p>The reason for the errors is that <codeph>MyLibLibFun1</codeph> and <codeph>MyLibLibFun3</codeph> use <codeph>typedef</codeph> datatypes. There is no issue with <codeph>MyLibLibFun2()</codeph> since
       
   123 it does not use <codeph>typedef</codeph> datatypes. To overcome these errors,
       
   124 the user must keep both the declaration and the definition within extern "C"
       
   125 linkage.</p><codeblock xml:space="preserve">/*File: SampleDLL.h*/    
       
   126 #ifndef SAMPLEDLL_H  
       
   127 #define SAMPLEDLL_H  
       
   128 /*extern "C" is used for declaration also*/
       
   129 
       
   130 typedef int MyInt;  
       
   131 typedef int (*MyFunPtr) ();    
       
   132 
       
   133 #ifdef __cplusplus  
       
   134 extern "C" {  
       
   135 #endif //__cplusplus    
       
   136 
       
   137 IMPORT_C int MyLibLibFun1(MyInt aParam);  
       
   138 IMPORT_C int MyLibLibFun3(MyFunPtr);  
       
   139 IMPORT_C int MyLibLibFun2(int (*MyFun1)());    
       
   140 
       
   141 #ifdef __cplusplus  
       
   142 }  
       
   143 #endif //__cplusplus    
       
   144 
       
   145 #endif /*SAMPLEDLL_H*/ </codeblock><p>When everything is within extern "C"
       
   146 (extern "C" in header and implementation), the DEF file for <codeph>ARMv5</codeph> and <codeph>WINSCW</codeph> looks
       
   147 as follows:</p><codeblock xml:space="preserve">EXPORTS
       
   148     MyLibLibFun1 @ 1 NONAME
       
   149     MyLibLibFun2 @ 2 NONAME
       
   150     MyLibLibFun3 @ 3 NONAME </codeblock><p>So, as one can observe in the above
       
   151 section where different DEF file entries are created with and without extern
       
   152 "C", the user must make sure that the rule is followed. extern "C" has to
       
   153 be used in both declaration and definition: otherwise the user will either,
       
   154 not be able to build it for all the platforms or, it will not be possible
       
   155 to use those exported C APIs in other applications. </p>     </section>
       
   156 </conbody></concept>