Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with HTTPS or Subversion.

Download ZIP
tree: 8249376bf9
Fetching contributors…

Cannot retrieve contributors at this time

622 lines (476 sloc) 21.245 kb
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01//EN" "http://www.w3.org/TR/html4/strict.dtd">
<html lang="en-US">
<!--
Copyright (c) 1999-2012 by Digital Mars
All Rights Reserved Written by Walter Bright
http://digitalmars.com
-->
<head>
<meta http-equiv="content-type" content="text/html; charset=utf-8" />
<meta name="keywords" content="D programming language" />
<meta name="description" content="D Programming Language" />
<title>Converting C .h Files to D Modules - D Programming Language</title>
<link rel="stylesheet" type="text/css" href="css/style.css" />
<link rel="stylesheet" type="text/css" href="css/print.css" media="print" />
<link rel="shortcut icon" href="favicon.ico" />
<script src="/js/hyphenate_selectively.js" type="text/javascript"></script>
<script type="text/javascript">
function bodyLoad()
{
var links = document.getElementById("navigation").getElementsByTagName("a");
for (var i = 0; i < links.length; i++)
{
var url = "/" + links[i].getAttribute("href");
if (window.location.href.match(url + "\x24") == url)
{
var cls = links[i].getAttribute("class");
links[i].setAttribute("class", cls ? cls + " active" : "active");
break;
}
}
}
</script>
<script type="text/javascript">
/*
(C) www.dhtmlgoodies.com, September 2005
This is a script from www.dhtmlgoodies.com. You will find this and a lot of other scripts at our website.
Terms of use:
You are free to use this script as long as the copyright message is kept intact. However, you may not
redistribute, sell or repost it without our permission.
Thank you!
www.dhtmlgoodies.com
Alf Magne Kalleland
*/
function showHideAnswer(zis)
{
var numericID = zis.id.replace(/[^\d]/g,'');
var obj = document.getElementById('a' + numericID);
if(obj.style.display=='block'){
zis.innerHTML = '<span class="nobr">See example.</span>';
obj.style.display='none';
}else{
zis.innerHTML = '<span class="nobr">Hide example.</span>';
obj.style.display='block';
}
}
</script>
</head>
<body onLoad='bodyLoad()'>
<div id="top">
<div id="search-box">
<form method="get" action="http://google.com/search">
<img src="/images/search-left.gif" width="11" height="22" /><input id="q" name="q" /><input type="image" id="search-submit" name="submit" src="/images/search-button.gif" />
<input type="hidden" id="domains" name="domains" value="d-programming-language.org" />
<input type="hidden" id="sourceid" name="sourceid" value="google-search" />
<div id="search-dropdown">
<select id="sitesearch" name="sitesearch" size="1">
<option value="d-programming-language.org">Entire D Site</option>
<option value="d-programming-language.org/phobos">Library Reference</option>
<option value="digitalmars.com/d/archives">Newsgroup Archives</option>
</select>
</div>
</form>
</div>
<div id="header">
<a id="d-language" href="/">
<img id="logo" width="125" height="95" border="0" alt="D Logo" src="images/dlogo.png">
D Programming Language</a>
</div>
</div>
<!-- Generated by Ddoc from htomodule.dd -->
<div id="navigation">
<div class="navblock">
<h2><a href="index.html" title="D Programming Language">D Home</a></h2>
<ul> <li><a href="overview.html" title="D language overview">Overview</a></li>
<li><a href="comparison.html" title="D feature list">Features</a></li>
<li><a href="download.html" title="Download a D compiler">Downloads &amp; Tools</a></li>
<li><a href="changelog.html" title="History of changes to D">Changelog</a></li>
<li><a href="bugstats.php" title="D issue and bug tracking system">Bug tracker</a></li>
<li><a href="faq.html" title="Frequently Asked Questions">FAQ</a></li>
<li><a href="appendices.html">Appendices</a></li>
<li><a href="acknowledgements.html" title="Thank-you to these people who have helped with D">Acknowledgments</a></li>
<li><a href="sitemap.html" title="Documents on this site, indexed alphabetically">Sitemap</a></li>
<li><a href="http://digitalmars.com/d/1.0/index.html" title="D Programming Language 1.0">D1 Home</a></li>
</ul>
</div>
<div class="navblock">
<h2>Documentation</h2>
<ul> <li><a href="http://www.amazon.com/exec/obidos/ASIN/0321635361/classicempire">Book</a>
</li>
<li><a href="http://www.informit.com/articles/article.aspx?p=1381876">&nbsp;<font size=-1><span style="visibility: hidden">3</span>1.&nbsp;Tutorial</font></a></li>
<li><a href="http://www.informit.com/articles/article.aspx?p=1609144">&nbsp;<font size=-1>13.&nbsp;Concurrency</font></a></li>
<li><a href="language-reference.html">Language Reference</a></li>
<li><a href="phobos/index.html">Library Reference</a></li>
<li><a href="howtos.html" title="Helps for using D">Howtos</a>
<div class="navblock">
<ul> <li><a href="windows.html" title="D implementation for 32 bit Windows systems">D for Win32</a></li>
<li><a href="dll.html" title="Writing 32 bit Windows DLLs in D">Win32 DLLs in D</a></li>
<li><a href="COM.html" title="Windows COM Programming">COM Programming</a></li>
<li><a href="32-64-portability.html" title="Porting 32 Bit Code to 64 Bits">Porting to 64 Bits</a></li>
<li><a href="htomodule.html" title="converting C .h header files to D modules">C .h to D Modules</a></li>
<li><a href="http://digitalmars.com/techtips/index.html" title="Programming tips">Tech Tips</a></li>
</ul>
</div>
</li>
<li><a href="articles.html">Articles</a></li>
</ul>
</div>
<div class="navblock">
<h2>Community</h2>
<ul> <li><a href="http://digitalmars.com/NewsGroup.html" title="User forums">Forums</a></li>
<li><a href="http://github.com/D-Programming-Language" title="D on github">Github</a></li>
<li><a href="http://prowiki.org/wiki4d/wiki.cgi?FrontPage" title="Wiki for the D Programming Language">Wiki</a></li>
<li><a href="http://prowiki.org/wiki4d/wiki.cgi?ReviewQueue" title="Queue of current and upcoming standard library additions">Review queue</a></li>
<li><a href="http://twitter.com/#search?q=%23d_lang" title="#d_lang on twitter.com">Twitter</a></li>
<li><a href="http://digitalmars.com/d/dlinks.html" title="External D related links">Links</a></li>
</ul>
</div>
<div id="translate" class="tool">Translate this page:
<div id="google_translate_element"></div><script type="text/javascript">
function googleTranslateElementInit() {
new google.translate.TranslateElement({
pageLanguage: 'en',
autoDisplay: false,
layout: google.translate.TranslateElement.InlineLayout.SIMPLE
}, 'google_translate_element');
}
</script>
<script type="text/javascript" src="http://translate.google.com/translate_a/element.js?cb=googleTranslateElementInit"></script>
</div>
</div><!--/navigation-->
<div id="content" class='hyphenate'>
<div id="tools">
<!--span id="lastupdate">Last update Mon Mar 5 00:18:19 2012
</span-->
<span id="wiki"><a href="http://www.prowiki.org/wiki4d/wiki.cgi?DocComments/HToModule">Comment on this page</a></span>
</div>
<h1>Converting C .h Files to D Modules</h1>
While D cannot directly compile C source code, it can easily
interface to C code, be linked with C object files, and call
C functions in DLLs.
The interface to C code is normally found in C <span class="notranslate"><span class="d_inlinecode">.h</span></span> files.
So, the trick to connecting with C code is in converting C
<span class="notranslate"><span class="d_inlinecode">.h</span></span> files to D modules.
This turns out to be difficult to do mechanically since
inevitably some human judgement must be applied.
This is a guide to doing such conversions.
<h4>Preprocessor</h4>
<span class="notranslate"><span class="d_inlinecode">.h</span></span> files can sometimes be a bewildering morass of layers of
macros, <span class="notranslate"><span class="d_inlinecode">#include</span></span> files, <span class="notranslate"><span class="d_inlinecode">#ifdef</span></span>'s, etc. D doesn't
include a text preprocessor like the C preprocessor,
so the first step is to remove the need for
it by taking the preprocessed output. For DMC (the Digital
Mars C/C++ compiler), the command:
<pre class="console"><span class="notranslate"><a href="http://www.digitalmars.com/ctg/sc.html">dmc</a> <a href="http://www.digitalmars.com/ctg/sc.html#dashc">-c</a> program.h <a href="http://www.digitalmars.com/ctg/sc.html#dashe">-e</a> <a href="http://www.digitalmars.com/ctg/sc.html#dashl">-l</a>
</span></pre>
will create a file <span class="notranslate"><span class="d_inlinecode">program.lst</span></span> which is the source file after
all text preprocessing.
<p>
Remove all the <span class="notranslate"><span class="d_inlinecode">#if</span></span>, <span class="notranslate"><span class="d_inlinecode">#ifdef</span></span>, <span class="notranslate"><span class="d_inlinecode">#include</span></span>,
etc. statements.
<h4>Linkage</h4>
Generally, surround the entire module with:
<pre class="d_code"><span class="notranslate"><span class="d_keyword">extern</span> (C)
{
<span class="d_comment">/* ...file contents... */</span>
}
</span></pre>
to give it C linkage.
<h4>Types</h4>
A little global search and replace will take care of renaming
the C types to D types. The following table shows a typical mapping
for 32 bit C code:
<p>
<table border=1 cellpadding=4 cellspacing=0> <caption>Mapping C type to D type</caption>
<tr>
<th>C type
<th>D type
<tr>
<td>long double
<td>real
<tr>
<td>unsigned long long
<td>ulong
<tr>
<td>long long
<td>long
<tr>
<td>unsigned long
<td>uint
<tr>
<td>long
<td>int
<tr>
<td>unsigned
<td>uint
<tr>
<td>unsigned short
<td>ushort
<tr>
<td>signed char
<td>byte
<tr>
<td>unsigned char
<td>ubyte
<tr>
<td>wchar_t
<td>wchar or dchar
<tr>
<td>bool
<td>bool, byte, int
<tr>
<td>size_t
<td>size_t
<tr>
<td>ptrdiff_t
<td>ptrdiff_t
</table>
<h4>NULL</h4>
<span class="notranslate"><span class="d_inlinecode">NULL</span></span> and <span class="notranslate"><span class="d_inlinecode">((void*)0)</span></span> should be replaced
with <span class="notranslate"><span class="d_inlinecode">null</span></span>.
<h4>Numeric Literals</h4>
Any &lsquo;L&rsquo; or &lsquo;l&rsquo; numeric literal suffixes should be removed,
as a C <span class="notranslate"><span class="d_inlinecode">long</span></span> is (usually) the same size as a D <span class="notranslate"><span class="d_inlinecode">int</span></span>.
Similarly, &lsquo;LL&rsquo; suffixes should be replaced with a
single &lsquo;L&rsquo;.
Any &lsquo;u&rsquo; suffix will work the same in D.
<h4>String Literals</h4>
In most cases, any &lsquo;L&rsquo; prefix to a string can just be dropped,
as D will implicitly convert strings to wide characters if
necessary. However, one can also replace:
<pre class="ccode"><span class="notranslate">L"string"
</span></pre>
with:
<pre class="d_code"><span class="notranslate"><span class="d_string">"string"w</span> <span class="d_comment">// for 16 bit wide characters
</span><span class="d_string">"string"d</span> <span class="d_comment">// for 32 bit wide characters
</span></span></pre>
<h4>Macros</h4>
Lists of macros like:
<pre class="ccode"><span class="notranslate">#define FOO 1
#define BAR 2
#define ABC 3
#define DEF 40
</span></pre>
can be replaced with:
<pre class="d_code"><span class="notranslate"><span class="d_keyword">enum</span>
{ FOO = 1,
BAR = 2,
ABC = 3,
DEF = 40
}
</span></pre>
or with:
<pre class="d_code"><span class="notranslate"><span class="d_keyword">const</span> <span class="d_keyword">int</span> FOO = 1;
<span class="d_keyword">const</span> <span class="d_keyword">int</span> BAR = 2;
<span class="d_keyword">const</span> <span class="d_keyword">int</span> ABC = 3;
<span class="d_keyword">const</span> <span class="d_keyword">int</span> DEF = 40;
</span></pre>
Function style macros, such as:
<pre class="ccode"><span class="notranslate">#define MAX(a,b) ((a) &lt; (b) ? (b) : (a))
</span></pre>
can be replaced with functions:
<pre class="d_code"><span class="notranslate"><span class="d_keyword">int</span> MAX(<span class="d_keyword">int</span> a, <span class="d_keyword">int</span> b) { <span class="d_keyword">return</span> (a &lt; b) ? b : a; }
</span></pre>
<!-- Thanks to Jarrett Billingsley for the following tip -->
The functions, however, won't work if they appear inside static
initializers that must be evaluated at compile time rather than
runtime. To do it at compile time, a template can be used:
<pre class="ccode"><span class="notranslate">#define GT_DEPTH_SHIFT (0)
#define GT_SIZE_SHIFT (8)
#define GT_SCHEME_SHIFT (24)
#define GT_DEPTH_MASK (0xffU &lt;&lt; GT_DEPTH_SHIFT)
#define GT_TEXT ((0x01) &lt;&lt; GT_SCHEME_SHIFT)
/* Macro that constructs a graphtype */
#define GT_CONSTRUCT(depth,scheme,size) \
((depth) | (scheme) | ((size) &lt;&lt; GT_SIZE_SHIFT))
/* Common graphtypes */
#define GT_TEXT16 GT_CONSTRUCT(4, GT_TEXT, 16)
</span></pre>
The corresponding D version would be:
<pre class="d_code"><span class="notranslate"><span class="d_keyword">const</span> <span class="d_keyword">uint</span> GT_DEPTH_SHIFT = 0;
<span class="d_keyword">const</span> <span class="d_keyword">uint</span> GT_SIZE_SHIFT = 8;
<span class="d_keyword">const</span> <span class="d_keyword">uint</span> GT_SCHEME_SHIFT = 24;
<span class="d_keyword">const</span> <span class="d_keyword">uint</span> GT_DEPTH_MASK = 0xffU &lt;&lt; GT_DEPTH_SHIFT;
<span class="d_keyword">const</span> <span class="d_keyword">uint</span> GT_TEXT = 0x01 &lt;&lt; GT_SCHEME_SHIFT;
<span class="d_comment">// Template that constructs a graphtype
</span><span class="d_keyword">template</span> GT_CONSTRUCT(<span class="d_keyword">uint</span> depth, <span class="d_keyword">uint</span> scheme, <span class="d_keyword">uint</span> size)
{
<span class="d_comment">// notice the name of the const is the same as that of the template
</span> <span class="d_keyword">const</span> <span class="d_keyword">uint</span> GT_CONSTRUCT = (depth | scheme | (size &lt;&lt; GT_SIZE_SHIFT));
}
<span class="d_comment">// Common graphtypes
</span><span class="d_keyword">const</span> <span class="d_keyword">uint</span> GT_TEXT16 = GT_CONSTRUCT!(4, GT_TEXT, 16);
</span></pre>
<h4>Declaration Lists</h4>
D doesn't allow declaration lists to change the type.
Hence:
<pre class="ccode"><span class="notranslate">int *p, q, t[3], *s;
</span></pre>
should be written as:
<pre class="d_code"><span class="notranslate"><span class="d_keyword">int</span>* p, s;
<span class="d_keyword">int</span> q;
<span class="d_keyword">int</span>[3] t;
</span></pre>
<h4>Void Parameter Lists</h4>
Functions that take no parameters:
<pre class="ccode"><span class="notranslate">int foo(void);
</span></pre>
are in D:
<pre class="d_code"><span class="notranslate"><span class="d_keyword">int</span> foo();
</span></pre>
<h4>Extern Global C Variables</h4>
Whenever a global variable is declared in D, it is also defined.
But if it's also defined by the C object file being linked in,
there will be a multiple definition error. To fix this problem,
use the extern storage class.
For example, given a C header file named
<span class="notranslate"><span class="d_inlinecode">foo.h</span></span>:
<pre class="ccode"><span class="notranslate">struct Foo { };
struct Foo bar;
</span></pre>
It can be replaced with the D modules, <span class="notranslate"><span class="d_inlinecode">foo.d</span></span>:
<pre class="d_code"><span class="notranslate"><span class="d_keyword">struct</span> Foo { }
<span class="d_keyword">extern</span> (C)
{
<span class="d_keyword">extern</span> Foo bar;
}
</span></pre>
<h4>Typedef</h4>
<span class="notranslate"><span class="d_inlinecode">alias</span></span> is the D equivalent to the C <span class="notranslate"><span class="d_inlinecode">typedef</span></span>:
<pre class="ccode"><span class="notranslate">typedef int foo;
</span></pre>
becomes:
<pre class="d_code"><span class="notranslate"><span class="d_keyword">alias</span> <span class="d_keyword">int</span> foo;
</span></pre>
<h4>Structs</h4>
Replace declarations like:
<pre class="ccode"><span class="notranslate">typedef struct Foo
{ int a;
int b;
} Foo, *pFoo, *lpFoo;
</span></pre>
with:
<pre class="d_code"><span class="notranslate"><span class="d_keyword">struct</span> Foo
{ <span class="d_keyword">int</span> a;
<span class="d_keyword">int</span> b;
}
<span class="d_keyword">alias</span> Foo* pFoo, lpFoo;
</span></pre>
<h4>Struct Member Alignment</h4>
A good D implementation by default will align struct members the
same way as the C compiler it was designed to work with. But
if the <span class="notranslate"><span class="d_inlinecode">.h</span></span> file has some <span class="notranslate"><span class="d_inlinecode">#pragma</span></span>'s to control alignment, they
can be duplicated with the D <span class="notranslate"><span class="d_inlinecode">align</span></span> attribute:
<pre class="ccode"><span class="notranslate">#pragma pack(1)
struct Foo
{
int a;
int b;
};
#pragma pack()
</span></pre>
becomes:
<pre class="d_code"><span class="notranslate"><span class="d_keyword">struct</span> Foo
{
<span class="d_keyword">align</span> (1):
<span class="d_keyword">int</span> a;
<span class="d_keyword">int</span> b;
}
</span></pre>
<h4>Nested Structs</h4>
<pre class="ccode"><span class="notranslate">struct Foo
{
int a;
struct Bar
{
int c;
} bar;
};
struct Abc
{
int a;
struct
{
int c;
} bar;
};
</span></pre>
becomes:
<pre class="d_code"><span class="notranslate"><span class="d_keyword">struct</span> Foo
{
<span class="d_keyword">int</span> a;
<span class="d_keyword">struct</span> Bar
{
<span class="d_keyword">int</span> c;
}
Bar bar;
}
<span class="d_keyword">struct</span> Abc
{
<span class="d_keyword">int</span> a;
<span class="d_keyword">struct</span>
{
<span class="d_keyword">int</span> c;
}
}
</span></pre>
<h4><span class="notranslate"><span class="d_inlinecode">__cdecl</span></span>, <span class="notranslate"><span class="d_inlinecode">__pascal</span></span>, <span class="notranslate"><span class="d_inlinecode">__stdcall</span></span></h4>
<pre class="ccode"><span class="notranslate">int __cdecl x;
int __cdecl foo(int a);
int __pascal bar(int b);
int __stdcall abc(int c);
</span></pre>
becomes:
<pre class="d_code"><span class="notranslate"><span class="d_keyword">extern</span> (C) <span class="d_keyword">int</span> x;
<span class="d_keyword">extern</span> (C) <span class="d_keyword">int</span> foo(<span class="d_keyword">int</span> a);
<span class="d_keyword">extern</span> (Pascal) <span class="d_keyword">int</span> bar(<span class="d_keyword">int</span> b);
<span class="d_keyword">extern</span> (Windows) <span class="d_keyword">int</span> abc(<span class="d_keyword">int</span> c);
</span></pre>
<h4><span class="notranslate"><span class="d_inlinecode">__declspec(dllimport)</span></span></h4>
<pre class="ccode"><span class="notranslate">__declspec(dllimport) int __stdcall foo(int a);
</span></pre>
becomes:
<pre class="d_code"><span class="notranslate"><span class="d_keyword">export</span> <span class="d_keyword">extern</span> (Windows) <span class="d_keyword">int</span> foo(<span class="d_keyword">int</span> a);
</span></pre>
<h4><span class="notranslate"><span class="d_inlinecode">__fastcall</span></span></h4>
Unfortunately, D doesn't support the <span class="notranslate"><span class="d_inlinecode">__fastcall</span></span> convention.
Therefore, a shim will be needed, either written in C:
<pre class="ccode"><span class="notranslate">int __fastcall foo(int a);
int myfoo(int a)
{
return foo(int a);
}
</span></pre>
and compiled with a C compiler that supports <span class="notranslate"><span class="d_inlinecode">__fastcall</span></span> and
linked in, or compile the above, disassemble it with
<a href="http://www.digitalmars.com/ctg/obj2asm.html">obj2asm</a>
and insert it in a D <span class="notranslate"><span class="d_inlinecode">myfoo</span></span> shim with
<a href="iasm.html">inline assembler</a>.
<div id="google_ad">
<!-- Google ad -->
<script type="text/javascript"><!--
/**/google_ad_client = "pub-5628673096434613";
/**/google_ad_width = 728;
/**/google_ad_height = 90;
/**/google_ad_format = "728x90_as";
/**/google_ad_channel ="3651639259";
/**/google_page_url = document.location;
//--></script>
<script type="text/javascript" src="http://pagead2.googlesyndication.com/pagead/show_ads.js">
</script>
</div>
</div><!--/content-->
<div id="footernav">
<a href="http://digitalmars.com/NewsGroup.html" title="User Forums">Forums</a> |
<a href="http://www.prowiki.org/wiki4d/wiki.cgi?DocComments/HToModule" title="Read/write comments and feedback">Comments</a> |
<a href="http://digitalmars.com/advancedsearch.html" title="Search Digital Mars web site">Search</a> |
<a href="download.html" title="Download D">Downloads</a> |
<a href="/">Home</a>
</div>
<div id="copyright">
Copyright &copy; 1999-2012 by Digital Mars &reg;, All Rights Reserved
|
Page generated by <a href="ddoc.html">Ddoc</a> on Mon Mar 5 00:18:19 2012
</div>
</body>
</html>
Jump to Line
Something went wrong with that request. Please try again.