Symbian3/SDK/Source/GUID-E2B67F14-EC4E-41B6-9F8E-AB58B9E8D7B6.dita
changeset 7 51a74ef9ed63
parent 0 89d6a7a84779
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/Symbian3/SDK/Source/GUID-E2B67F14-EC4E-41B6-9F8E-AB58B9E8D7B6.dita	Wed Mar 31 11:11:55 2010 +0100
@@ -0,0 +1,156 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Copyright (c) 2007-2010 Nokia Corporation and/or its subsidiary(-ies) All rights reserved. -->
+<!-- This component and the accompanying materials are made available under the terms of the License 
+"Eclipse Public License v1.0" which accompanies this distribution, 
+and is available at the URL "http://www.eclipse.org/legal/epl-v10.html". -->
+<!-- Initial Contributors:
+    Nokia Corporation - initial contribution.
+Contributors: 
+-->
+<!DOCTYPE concept
+  PUBLIC "-//OASIS//DTD DITA Concept//EN" "concept.dtd">
+<concept id="GUID-E2B67F14-EC4E-41B6-9F8E-AB58B9E8D7B6" xml:lang="en"><title>extern
+"C" and Symbian DEF files</title><shortdesc/><prolog><metadata><keywords/></metadata></prolog><conbody>
+<p>This article gives a general idea about the Symbian DEF file. Whenever
+developers write any DLLs that export a set of APIs to the user, there will
+be an entry for each exported API in the DEF file created. The developer will
+use:</p>
+<ul>
+<li><p><codeph>IMPORT_C</codeph> while declaring exported APIs</p></li>
+<li><p><codeph>EXPORT_C</codeph> while defining such APIs</p></li>
+</ul>
+<p>After building the application for the first time, it lists all the newly
+exported APIs. After doing a freeze (for which the <cmdname>abld freeze winscw</cmdname> and <cmdname>abld
+freeze armv5</cmdname> commands are used), the DEF files will be created under <filepath>BWINS</filepath> and <filepath>EABI</filepath> folders
+within the project directory. These DEF files are used to create <filepath>.lib</filepath> files
+for DLLs. In the DEF file, for each exported API, there will be mapping between
+its prototype and a number will be present.  </p>
+<p>Let's assume that directory structure used for implementing a library is
+as shown below:</p>
+<ul>
+<li><p><filepath>LibraryName\group</filepath> -- <filepath>bld.inf</filepath> and <filepath>LibraryName.mmp</filepath> (all
+build-related files)</p></li>
+<li><p><filepath>LibraryName\inc</filepath> -- All project-specific headers
+(user include headers)</p></li>
+<li><p><filepath>LibraryName\src</filepath> -- All project-specific source
+files </p></li>
+</ul>
+<p>If a developer is building the library for the first time, the developer
+should follow these steps and give the following commands from <filepath>LibraryName\group</filepath>: </p>
+<ol>
+<li id="GUID-DE29CFD9-77C2-4790-89C6-5491F3EBA922"><p>Create the <filepath>abld.bat</filepath> file
+for the project. </p><codeblock xml:space="preserve">LibraryName\group&gt;bldmake bldfiles</codeblock></li>
+<li id="GUID-DC6AE0F4-64C6-432B-826B-26B7CDA8565C"><p>Build the project for
+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>
+<li id="GUID-836865DB-F613-4000-95AC-DDC9E3F498B2"><p>Create the DEF file
+for the default platform (<filepath>LibraryName\BWINS\LibraryNameu.def and
+LibraryName\EABI\LibraryNameu.def</filepath>). </p><codeblock xml:space="preserve">LibraryName\group&gt;abld freeze</codeblock></li>
+<li id="GUID-C69111BA-1568-4CB4-8AB5-0EDEFC854D39"><p>Create <filepath>.lib</filepath> files
+for the DLL using DEF file entries. (<filepath>LibraryName.lib</filepath>) </p><codeblock xml:space="preserve">LibraryName\group&gt; abld build</codeblock></li>
+</ol>
+<p>The final step is required since applications that link with this library
+(<filepath>LibraryName.DLL</filepath>) will link with <filepath>LibraryName.lib</filepath> during
+link time. If the developer fails to perform the final step, the application
+will get a linker error because there is no <filepath>LibraryName.lib</filepath> present.</p>
+<section id="GUID-3AD1D783-C36F-4443-8957-6DB9434927B5">       <title>Rule
+for using extern "C"</title>       <p>When porting or writing libraries that
+export C APIs to the user, care should be taken to ensure that extern "C"
+is used properly if those APIs are implemented in a C++ source file. Otherwise
+these libraries may either not be built for the target platform (ARMV5) or
+the user of such library will get a linker error when using exported APIs
+of such library.  </p><p>If extern "C" is declared in the header and not defined
+in the source, then after building the library there will be a similar entry
+in DEF files. The compiler will not give external linkage to these APIs. This
+can be observed when trying to use these APIs from some other C source file.
+To overcome this, extern "C" must be present in both declarations and definitions.</p><p><b>Example
+code</b></p><codeblock xml:space="preserve">/*File: SampleDLL.h*/
+/*extern "C" is not used for declaration!*/ 
+#ifndef SAMPLEDLL_H
+#define SAMPLEDLL_H
+
+typedef int MyInt;
+typedef int (*MyFunPtr) ();
+
+IMPORT_C int MyLibLibFun1(MyInt aParam);
+IMPORT_C int MyLibLibFun3(MyFunPtr);
+IMPORT_C int MyLibLibFun2(int (*MyFun1)());
+
+#endif /*SAMPLEDLL_H*/
+
+
+
+//File: SampleDLL.cpp
+#include "SampleDLL.h"
+// extern "C" is used for definition
+extern "C"  {
+
+EXPORT_C int MyLibLibFun1(MyInt aParam)
+   {
+   return aParam + 10;
+   }
+
+EXPORT_C int MyLibLibFun2(int (*MyFun1)())
+   {
+   return MyFun1();
+   }
+
+EXPORT_C int MyLibLibFun3(MyFunPtr aPtr)
+   {
+   return aPtr();
+   }
+}
+</codeblock><p><b>Building for <codeph>WINSCW</codeph></b></p><p>This code
+will get compiled for <codeph>WINSCW</codeph>. The DEF file for <codeph>WINSCW</codeph> will
+have the following entries:</p><codeblock xml:space="preserve">EXPORTS
+     ?MyLibLibFun1@@YAHH@Z @ 1 NONAME ; int MyLibLibFun1(int)
+     ?MyLibLibFun2@@YAHP6AHXZ@Z @ 2 NONAME ; int MyLibLibFun2(int (*)(void))
+     ?MyLibLibFun3@@YAHP6AHXZ@Z @ 3 NONAME ; int MyLibLibFun3(int (*)(void)) </codeblock><p>If
+the user comments extern "C" from the above <filepath>SampleDLL.cpp</filepath> file,
+the DEF file entries will be the same.</p><p><b>Building for <codeph>ARMv5</codeph></b></p><p>If
+the user try's the above code without extern "C" in <filepath>SampleDLL.cpp</filepath>,
+the code will get built and the DEF file entry for <codeph>ARMv5</codeph> will
+be:</p><codeblock xml:space="preserve">EXPORTS
+     _Z12MyLibLibFun1i @ 1 NONAME
+     _Z12MyLibLibFun2PFivE @ 2 NONAME
+     _Z12MyLibLibFun3PFivE @ 3 NONAME  </codeblock><p>If the user keeps the
+extern "C" in <filepath>SampleDLL.cpp</filepath>, this code will not get compiled
+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")
+   EXPORT_C int MyLibLibFun1(MyInt aParam)
+                ^ 
+"..\src\Sampledll.cpp", line 17: Error:  #337: linkage specification is incompatible with previous "MyLibLibFun3" (declared at line 11 of "..\inc\SampleDLL.h")
+   EXPORT_C int MyLibLibFun3(MyFunPtr aPtr)
+               ^</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
+it does not use <codeph>typedef</codeph> datatypes. To overcome these errors,
+the user must keep both the declaration and the definition within extern "C"
+linkage.</p><codeblock xml:space="preserve">/*File: SampleDLL.h*/    
+#ifndef SAMPLEDLL_H  
+#define SAMPLEDLL_H  
+/*extern "C" is used for declaration also*/
+
+typedef int MyInt;  
+typedef int (*MyFunPtr) ();    
+
+#ifdef __cplusplus  
+extern "C" {  
+#endif //__cplusplus    
+
+IMPORT_C int MyLibLibFun1(MyInt aParam);  
+IMPORT_C int MyLibLibFun3(MyFunPtr);  
+IMPORT_C int MyLibLibFun2(int (*MyFun1)());    
+
+#ifdef __cplusplus  
+}  
+#endif //__cplusplus    
+
+#endif /*SAMPLEDLL_H*/ </codeblock><p>When everything is within extern "C"
+(extern "C" in header and implementation), the DEF file for <codeph>ARMv5</codeph> and <codeph>WINSCW</codeph> looks
+as follows:</p><codeblock xml:space="preserve">EXPORTS
+    MyLibLibFun1 @ 1 NONAME
+    MyLibLibFun2 @ 2 NONAME
+    MyLibLibFun3 @ 3 NONAME </codeblock><p>So, as one can observe in the above
+section where different DEF file entries are created with and without extern
+"C", the user must make sure that the rule is followed. extern "C" has to
+be used in both declaration and definition: otherwise the user will either,
+not be able to build it for all the platforms or, it will not be possible
+to use those exported C APIs in other applications. </p>     </section>
+</conbody></concept>
\ No newline at end of file