<?xml version="1.0" encoding="utf-8" standalone="yes"?><rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom"><channel><title>C on dev@iostream.pl</title><link>https://dev.iostream.pl/tags/c/</link><description>Recent content in C on dev@iostream.pl</description><generator>Hugo -- gohugo.io</generator><language>en-us</language><lastBuildDate>Mon, 22 Jun 2026 20:05:00 +0200</lastBuildDate><atom:link href="https://dev.iostream.pl/tags/c/index.xml" rel="self" type="application/rss+xml"/><item><title>2026-06-22</title><link>https://dev.iostream.pl/posts/2026-06-22/</link><pubDate>Mon, 22 Jun 2026 20:05:00 +0200</pubDate><guid>https://dev.iostream.pl/posts/2026-06-22/</guid><description>
 &lt;blockquote&gt;
 &lt;p&gt;The original version of this article was written in 2006.&lt;/p&gt;
&lt;p&gt;Back then:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Python 2 was still alive,&lt;/li&gt;
&lt;li&gt;distutils existed,&lt;/li&gt;
&lt;li&gt;XEmacs was technically not dead,&lt;/li&gt;
&lt;li&gt;and people still owned VHS tapes.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Let&amp;rsquo;s see how much of this still works in 2026.&lt;/p&gt;

 &lt;/blockquote&gt;
&lt;h1 id="modules-lies-and-vhs-tapes"&gt;Modules, Lies, and VHS Tapes
&lt;/h1&gt;&lt;p&gt;Sometimes you need to write Python bindings for a strange third-party library. It happens.&lt;/p&gt;
&lt;p&gt;Sometimes you need to write the library itself. That happens too.&lt;/p&gt;
&lt;p&gt;And sometimes you have to do all of that on Windows using GNU tools.&lt;/p&gt;
&lt;p&gt;This article serves both as a professional tutorial and as a public service announcement suggesting that you abandon everything and move to a remote mountain cabin. Mostly because I can never remember the correct order of the steps involved.&lt;/p&gt;
&lt;h2 id="prerequisites-on-windows"&gt;Prerequisites on Windows
&lt;/h2&gt;&lt;p&gt;The easiest approach is to use MSYS2 and GCC.&lt;/p&gt;
&lt;p&gt;You should have the following tools available somewhere in your PATH:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;GCC&lt;/li&gt;
&lt;li&gt;Python&lt;/li&gt;
&lt;li&gt;&lt;code&gt;dlltool&lt;/code&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Nothing particularly exotic.&lt;/p&gt;
&lt;h2 id="a-sample-library"&gt;A Sample Library
&lt;/h2&gt;&lt;p&gt;Our example library is intentionally simple. It contains only two functions: one that adds two integers and one that multiplies them.&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"&gt;&lt;code class="language-c" data-lang="c"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#66d9ef"&gt;int&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;mul2x&lt;/span&gt;(&lt;span style="color:#66d9ef"&gt;int&lt;/span&gt; x, &lt;span style="color:#66d9ef"&gt;int&lt;/span&gt; y)
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;{
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#66d9ef"&gt;return&lt;/span&gt; x &lt;span style="color:#f92672"&gt;*&lt;/span&gt; y;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;}
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#66d9ef"&gt;int&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;add2x&lt;/span&gt;(&lt;span style="color:#66d9ef"&gt;int&lt;/span&gt; x, &lt;span style="color:#66d9ef"&gt;int&lt;/span&gt; y)
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;{
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#66d9ef"&gt;return&lt;/span&gt; x &lt;span style="color:#f92672"&gt;+&lt;/span&gt; y;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;}
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;Since the library is simple, let&amp;rsquo;s call it &lt;code&gt;SimpLib&lt;/code&gt;.&lt;/p&gt;
&lt;p&gt;Assume the source code is stored in a file called &lt;code&gt;simplib.c&lt;/code&gt;.&lt;/p&gt;
&lt;h2 id="building-the-library"&gt;Building the Library
&lt;/h2&gt;&lt;p&gt;As always, source files should first be compiled into object files.&lt;/p&gt;
&lt;p&gt;To produce a shared library, GCC requires the &lt;code&gt;-shared&lt;/code&gt; option.&lt;/p&gt;

 &lt;blockquote&gt;
 &lt;p&gt;Following Unix naming conventions, shared libraries usually have a &lt;code&gt;lib&lt;/code&gt; prefix and a &lt;code&gt;.so&lt;/code&gt; extension. Linking with &lt;code&gt;-lname&lt;/code&gt; assumes the presence of a library named &lt;code&gt;libname.so&lt;/code&gt; somewhere on the library search path. Many GNU projects ported to Windows continue to use this naming convention internally, even though the final artifact is a &lt;code&gt;.dll&lt;/code&gt;.&lt;/p&gt;

 &lt;/blockquote&gt;
&lt;h3 id="linux"&gt;Linux
&lt;/h3&gt;&lt;div class="highlight"&gt;&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;gcc -o simplib.o -c simplib.c
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;gcc -o libsimp.so simplib.o -shared
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;Of course, for a single source file you could simply write:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;gcc -o libsimp.so simplib.c -shared
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;However, once a project grows beyond a trivial example, compiling each source file separately and linking everything at the end is usually a much better idea.&lt;/p&gt;
&lt;p&gt;Congratulations. The library has been built and is ready for use.&lt;/p&gt;
&lt;p&gt;&lt;em&gt;Cue triumphant fanfare.&lt;/em&gt;&lt;/p&gt;
&lt;h3 id="windows"&gt;Windows
&lt;/h3&gt;&lt;p&gt;Although we&amp;rsquo;re using exactly the same compiler, Windows requires one additional step.&lt;/p&gt;
&lt;p&gt;We need to create an &lt;strong&gt;import library&lt;/strong&gt; (sometimes called an interface library) that other applications can link against. This is where &lt;code&gt;dlltool&lt;/code&gt; enters the picture.&lt;/p&gt;
&lt;h4 id="creating-the-import-library"&gt;Creating the Import Library
&lt;/h4&gt;&lt;div class="highlight"&gt;&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;gcc -o simplib.o -c simplib.c
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;dlltool -l libsimp.lib simplib.o
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;gcc -o libsimp.dll simplib.o -shared
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;The DLL is now ready.&lt;/p&gt;
&lt;p&gt;The import library is also ready.&lt;/p&gt;
&lt;p&gt;&lt;em&gt;Cue Windows-themed fanfare.&lt;/em&gt;&lt;/p&gt;
&lt;h2 id="header-file"&gt;Header File
&lt;/h2&gt;&lt;p&gt;Providing a header file is generally considered a polite thing to do.&lt;/p&gt;
&lt;p&gt;Other developers will appreciate not having to reverse-engineer your function declarations, and they will be less inclined to say unpleasant things about you.&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"&gt;&lt;code class="language-c" data-lang="c"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#75715e"&gt;#ifndef __SIMPLIB_H__
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#75715e"&gt;#define __SIMPLIB_H__
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#66d9ef"&gt;int&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;mul2x&lt;/span&gt;(&lt;span style="color:#66d9ef"&gt;int&lt;/span&gt; x, &lt;span style="color:#66d9ef"&gt;int&lt;/span&gt; y);
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#66d9ef"&gt;int&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;add2x&lt;/span&gt;(&lt;span style="color:#66d9ef"&gt;int&lt;/span&gt; x, &lt;span style="color:#66d9ef"&gt;int&lt;/span&gt; y);
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#75715e"&gt;#endif
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;Assume this file is called &lt;code&gt;simplib.h&lt;/code&gt;.&lt;/p&gt;
&lt;h2 id="a-sample-c-program"&gt;A Sample C Program
&lt;/h2&gt;&lt;p&gt;The best way to test a library is to write a small program that uses it.&lt;/p&gt;

 &lt;blockquote&gt;
 &lt;p&gt;There are not many activities one can perform while fully clothed that are more enjoyable than programming, although surprisingly few people seem aware of this fact.&lt;/p&gt;

 &lt;/blockquote&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"&gt;&lt;code class="language-c" data-lang="c"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#75715e"&gt;#include&lt;/span&gt; &lt;span style="color:#75715e"&gt;&amp;lt;stdio.h&amp;gt;&lt;/span&gt;&lt;span style="color:#75715e"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#75715e"&gt;#include&lt;/span&gt; &lt;span style="color:#75715e"&gt;&amp;#34;simplib.h&amp;#34;&lt;/span&gt;&lt;span style="color:#75715e"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#66d9ef"&gt;int&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;main&lt;/span&gt;(&lt;span style="color:#66d9ef"&gt;int&lt;/span&gt; argc, &lt;span style="color:#66d9ef"&gt;char&lt;/span&gt; &lt;span style="color:#f92672"&gt;*&lt;/span&gt;argv[])
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;{
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#a6e22e"&gt;printf&lt;/span&gt;(&lt;span style="color:#e6db74"&gt;&amp;#34;Adding 5 to 10: %d&lt;/span&gt;&lt;span style="color:#ae81ff"&gt;\n&lt;/span&gt;&lt;span style="color:#e6db74"&gt;&amp;#34;&lt;/span&gt;, &lt;span style="color:#a6e22e"&gt;add2x&lt;/span&gt;(&lt;span style="color:#ae81ff"&gt;5&lt;/span&gt;, &lt;span style="color:#ae81ff"&gt;10&lt;/span&gt;));
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#a6e22e"&gt;printf&lt;/span&gt;(&lt;span style="color:#e6db74"&gt;&amp;#34;Multiplying 5 by 10: %d&lt;/span&gt;&lt;span style="color:#ae81ff"&gt;\n&lt;/span&gt;&lt;span style="color:#e6db74"&gt;&amp;#34;&lt;/span&gt;, &lt;span style="color:#a6e22e"&gt;mul2x&lt;/span&gt;(&lt;span style="color:#ae81ff"&gt;5&lt;/span&gt;, &lt;span style="color:#ae81ff"&gt;10&lt;/span&gt;));
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#66d9ef"&gt;return&lt;/span&gt; &lt;span style="color:#ae81ff"&gt;0&lt;/span&gt;;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;}
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;Assume this program is stored as &lt;code&gt;simprg.c&lt;/code&gt;.&lt;/p&gt;
&lt;h2 id="building-the-sample-program"&gt;Building the Sample Program
&lt;/h2&gt;&lt;h3 id="linux-1"&gt;Linux
&lt;/h3&gt;&lt;div class="highlight"&gt;&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;gcc -o simprg.o -c simprg.c
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;gcc -o simprg simprg.o -lsimp
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;h3 id="windows-1"&gt;Windows
&lt;/h3&gt;&lt;p&gt;Remember the import library:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;gcc -o simprg.o -c simprg.c
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;gcc -o simprg simprg.o libsimp.lib -lsimp
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;h3 id="a-brief-note-about-flags"&gt;A Brief Note About Flags
&lt;/h3&gt;&lt;p&gt;If the library is not located on the system library search path, remember to use the &lt;code&gt;-L&lt;/code&gt; option.&lt;/p&gt;
&lt;p&gt;Windows searches the current directory by default.&lt;/p&gt;
&lt;p&gt;Linux does not.&lt;/p&gt;
&lt;p&gt;For example:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;gcc -o simprg simprg.o -L. -lsimp
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;h2 id="writing-a-python-extension-module"&gt;Writing a Python Extension Module
&lt;/h2&gt;
 &lt;blockquote&gt;
 &lt;p&gt;Historical note&lt;/p&gt;
&lt;p&gt;The code below targets Python 2.x and reflects the state of the CPython API around 2006.
Modern Python 3 extension modules use a different initialization mechanism based on
&lt;code&gt;PyModuleDef&lt;/code&gt; and &lt;code&gt;PyModule_Create&lt;/code&gt;.&lt;/p&gt;

 &lt;/blockquote&gt;
&lt;p&gt;The following code demonstrates Python bindings for &lt;code&gt;SimpLib&lt;/code&gt;:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"&gt;&lt;code class="language-c" data-lang="c"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#75715e"&gt;#include&lt;/span&gt; &lt;span style="color:#75715e"&gt;&amp;lt;Python.h&amp;gt;&lt;/span&gt;&lt;span style="color:#75715e"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#75715e"&gt;#include&lt;/span&gt; &lt;span style="color:#75715e"&gt;&amp;#34;simplib.h&amp;#34;&lt;/span&gt;&lt;span style="color:#75715e"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#66d9ef"&gt;static&lt;/span&gt; PyObject &lt;span style="color:#f92672"&gt;*&lt;/span&gt;&lt;span style="color:#a6e22e"&gt;simp_mul2x&lt;/span&gt;(PyObject &lt;span style="color:#f92672"&gt;*&lt;/span&gt;self, PyObject &lt;span style="color:#f92672"&gt;*&lt;/span&gt;args)
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;{
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#66d9ef"&gt;int&lt;/span&gt; x, y, result;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; PyObject &lt;span style="color:#f92672"&gt;*&lt;/span&gt;pyresult;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#66d9ef"&gt;if&lt;/span&gt; (&lt;span style="color:#f92672"&gt;!&lt;/span&gt;&lt;span style="color:#a6e22e"&gt;PyArg_ParseTuple&lt;/span&gt;(args, &lt;span style="color:#e6db74"&gt;&amp;#34;ii&amp;#34;&lt;/span&gt;, &lt;span style="color:#f92672"&gt;&amp;amp;&lt;/span&gt;x;, &lt;span style="color:#f92672"&gt;&amp;amp;&lt;/span&gt;y;))
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; {
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#66d9ef"&gt;return&lt;/span&gt; NULL;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; }
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; result &lt;span style="color:#f92672"&gt;=&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;mul2x&lt;/span&gt;(x, y);
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; pyresult &lt;span style="color:#f92672"&gt;=&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;Py_BuildValue&lt;/span&gt;(&lt;span style="color:#e6db74"&gt;&amp;#34;i&amp;#34;&lt;/span&gt;, result);
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#66d9ef"&gt;return&lt;/span&gt; pyresult;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;}
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#66d9ef"&gt;static&lt;/span&gt; PyObject &lt;span style="color:#f92672"&gt;*&lt;/span&gt;&lt;span style="color:#a6e22e"&gt;simp_add2x&lt;/span&gt;(PyObject &lt;span style="color:#f92672"&gt;*&lt;/span&gt;self, PyObject &lt;span style="color:#f92672"&gt;*&lt;/span&gt;args)
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;{
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#66d9ef"&gt;int&lt;/span&gt; x, y, result;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; PyObject &lt;span style="color:#f92672"&gt;*&lt;/span&gt;pyresult;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#66d9ef"&gt;if&lt;/span&gt; (&lt;span style="color:#f92672"&gt;!&lt;/span&gt;&lt;span style="color:#a6e22e"&gt;PyArg_ParseTuple&lt;/span&gt;(args, &lt;span style="color:#e6db74"&gt;&amp;#34;ii&amp;#34;&lt;/span&gt;, &lt;span style="color:#f92672"&gt;&amp;amp;&lt;/span&gt;x;, &lt;span style="color:#f92672"&gt;&amp;amp;&lt;/span&gt;y;))
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; {
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#66d9ef"&gt;return&lt;/span&gt; NULL;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; }
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; result &lt;span style="color:#f92672"&gt;=&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;add2x&lt;/span&gt;(x, y);
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; pyresult &lt;span style="color:#f92672"&gt;=&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;Py_BuildValue&lt;/span&gt;(&lt;span style="color:#e6db74"&gt;&amp;#34;i&amp;#34;&lt;/span&gt;, result);
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#66d9ef"&gt;return&lt;/span&gt; pyresult;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;}
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#66d9ef"&gt;static&lt;/span&gt; PyMethodDef SimpMethods[] &lt;span style="color:#f92672"&gt;=&lt;/span&gt; {
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; {&lt;span style="color:#e6db74"&gt;&amp;#34;mul2x&amp;#34;&lt;/span&gt;, simp_mul2x, METH_VARARGS, &lt;span style="color:#e6db74"&gt;&amp;#34;Multiply two integer values&amp;#34;&lt;/span&gt;},
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; {&lt;span style="color:#e6db74"&gt;&amp;#34;add2x&amp;#34;&lt;/span&gt;, simp_add2x, METH_VARARGS, &lt;span style="color:#e6db74"&gt;&amp;#34;Add two integer values&amp;#34;&lt;/span&gt;},
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; {NULL, NULL, &lt;span style="color:#ae81ff"&gt;0&lt;/span&gt;, NULL}
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;};
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; 
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;PyMODINIT_FUNC &lt;span style="color:#a6e22e"&gt;initsimp&lt;/span&gt;(&lt;span style="color:#66d9ef"&gt;void&lt;/span&gt;)
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;{
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; (&lt;span style="color:#66d9ef"&gt;void&lt;/span&gt;) &lt;span style="color:#a6e22e"&gt;Py_InitModule&lt;/span&gt;(&lt;span style="color:#e6db74"&gt;&amp;#34;simp&amp;#34;&lt;/span&gt;, SimpMethods);
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;}
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;Assume the file is called &lt;code&gt;simpmodule.c&lt;/code&gt;.&lt;/p&gt;
&lt;h3 id="what-is-happening-here"&gt;What Is Happening Here?
&lt;/h3&gt;&lt;p&gt;Every extension module requires an initialization function.&lt;/p&gt;
&lt;p&gt;Historically, for Python 2.x, this function was named &lt;code&gt;init&lt;/code&gt; followed by the module name, hence:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"&gt;&lt;code class="language-c" data-lang="c"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#a6e22e"&gt;initsimp&lt;/span&gt;()
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;The initialization function creates the module object itself.&lt;/p&gt;
&lt;p&gt;Every function listed in the module&amp;rsquo;s method table becomes a method of that module.&lt;/p&gt;
&lt;p&gt;In our case:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"&gt;&lt;code class="language-c" data-lang="c"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#66d9ef"&gt;static&lt;/span&gt; PyMethodDef SimpMethods[]
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;contains:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;the names visible from Python,&lt;/li&gt;
&lt;li&gt;the addresses of the corresponding C functions,&lt;/li&gt;
&lt;li&gt;additional flags describing how arguments are passed.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;The &lt;code&gt;METH_VARARGS&lt;/code&gt; flag indicates that Python will pass arguments as a tuple.&lt;/p&gt;
&lt;p&gt;The binding functions themselves follow a simple pattern:&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;Validate input arguments.&lt;/li&gt;
&lt;li&gt;Perform the actual computation.&lt;/li&gt;
&lt;li&gt;Convert the result into a Python object.&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;Argument validation is handled by:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"&gt;&lt;code class="language-c" data-lang="c"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#a6e22e"&gt;PyArg_ParseTuple&lt;/span&gt;(args, &lt;span style="color:#e6db74"&gt;&amp;#34;ii&amp;#34;&lt;/span&gt;, &lt;span style="color:#f92672"&gt;&amp;amp;&lt;/span&gt;x, &lt;span style="color:#f92672"&gt;&amp;amp;&lt;/span&gt;y)
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;The format string &lt;code&gt;&amp;quot;ii&amp;quot;&lt;/code&gt; means:&lt;/p&gt;

 &lt;blockquote&gt;
 &lt;p&gt;I expect two arguments, and both of them must be integers.&lt;/p&gt;

 &lt;/blockquote&gt;
&lt;p&gt;If validation fails, the function should simply return &lt;code&gt;NULL&lt;/code&gt;.&lt;/p&gt;
&lt;p&gt;Building the return value is similarly straightforward:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"&gt;&lt;code class="language-c" data-lang="c"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#a6e22e"&gt;Py_BuildValue&lt;/span&gt;(&lt;span style="color:#e6db74"&gt;&amp;#34;i&amp;#34;&lt;/span&gt;, result);
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;which constructs a Python integer object.&lt;/p&gt;
&lt;p&gt;The Python documentation traditionally recommends declaring all binding functions as &lt;code&gt;static&lt;/code&gt;.&lt;/p&gt;
&lt;h2 id="building-the-module"&gt;Building the Module
&lt;/h2&gt;&lt;p&gt;One way to build the extension is to use &lt;code&gt;distutils&lt;/code&gt;.&lt;/p&gt;
&lt;h3 id="example-setuppy"&gt;Example setup.py
&lt;/h3&gt;&lt;div class="highlight"&gt;&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"&gt;&lt;code class="language-python" data-lang="python"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#75715e"&gt;#!/usr/bin/env python3&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#f92672"&gt;from&lt;/span&gt; distutils.core &lt;span style="color:#f92672"&gt;import&lt;/span&gt; setup, Extension
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;simpmodule &lt;span style="color:#f92672"&gt;=&lt;/span&gt; Extension(
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#e6db74"&gt;&amp;#39;simp&amp;#39;&lt;/span&gt;,
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; sources&lt;span style="color:#f92672"&gt;=&lt;/span&gt;[&lt;span style="color:#e6db74"&gt;&amp;#39;simpmodule.c&amp;#39;&lt;/span&gt;],
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; libraries&lt;span style="color:#f92672"&gt;=&lt;/span&gt;[&lt;span style="color:#e6db74"&gt;&amp;#39;simp&amp;#39;&lt;/span&gt;],
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; library_dirs&lt;span style="color:#f92672"&gt;=&lt;/span&gt;[&lt;span style="color:#e6db74"&gt;&amp;#39;.&amp;#39;&lt;/span&gt;]
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;)
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;setup(
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; name&lt;span style="color:#f92672"&gt;=&lt;/span&gt;&lt;span style="color:#e6db74"&gt;&amp;#39;SimpLib&amp;#39;&lt;/span&gt;,
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; version&lt;span style="color:#f92672"&gt;=&lt;/span&gt;&lt;span style="color:#e6db74"&gt;&amp;#39;1.0&amp;#39;&lt;/span&gt;,
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; description&lt;span style="color:#f92672"&gt;=&lt;/span&gt;&lt;span style="color:#e6db74"&gt;&amp;#39;This is SimpLib bindings package&amp;#39;&lt;/span&gt;,
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; ext_modules&lt;span style="color:#f92672"&gt;=&lt;/span&gt;[simpmodule]
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;)
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;The &lt;code&gt;Extension&lt;/code&gt; object describes:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;source files,&lt;/li&gt;
&lt;li&gt;required libraries,&lt;/li&gt;
&lt;li&gt;library search paths.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;The &lt;code&gt;setup()&lt;/code&gt; function handles the rest.&lt;/p&gt;
&lt;h3 id="linux-2"&gt;Linux
&lt;/h3&gt;&lt;div class="highlight"&gt;&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;python setup.py build
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;h3 id="windows-2"&gt;Windows
&lt;/h3&gt;&lt;p&gt;Unfortunately, Python traditionally expects Visual C++ when building extension modules.&lt;/p&gt;
&lt;p&gt;If that doesn&amp;rsquo;t bother you, feel free to use it.&lt;/p&gt;
&lt;p&gt;That would, however, make this article considerably shorter.&lt;/p&gt;
&lt;p&gt;To force MinGW:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;python setup.py build --compiler&lt;span style="color:#f92672"&gt;=&lt;/span&gt;mingw32
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;h2 id="installing-the-module"&gt;Installing the Module
&lt;/h2&gt;&lt;h3 id="linux-3"&gt;Linux
&lt;/h3&gt;&lt;div class="highlight"&gt;&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;python setup.py install
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;The extension and all required files will be installed into the appropriate Python directories.&lt;/p&gt;
&lt;h3 id="windows-3"&gt;Windows
&lt;/h3&gt;&lt;p&gt;The generated &lt;code&gt;simp.pyd&lt;/code&gt; file should be copied into either:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"&gt;&lt;code class="language-text" data-lang="text"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;Lib\site-packages
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;or&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"&gt;&lt;code class="language-text" data-lang="text"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;%APPDATA%\Roaming\Python\site-packages
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;Make sure you know which Python installation you&amp;rsquo;re targeting before copying files around.&lt;/p&gt;

 &lt;blockquote&gt;
 &lt;p&gt;If you happen to own Visual C++, and if the sight of it does not cause emotional distress, installation works exactly like it does on Linux.&lt;/p&gt;

 &lt;/blockquote&gt;
&lt;h2 id="a-short-test-program"&gt;A Short Test Program
&lt;/h2&gt;&lt;p&gt;Naturally, the best way to test the module is to use it.&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"&gt;&lt;code class="language-python" data-lang="python"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#f92672"&gt;from&lt;/span&gt; simp &lt;span style="color:#f92672"&gt;import&lt;/span&gt; &lt;span style="color:#f92672"&gt;*&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;print(&lt;span style="color:#e6db74"&gt;&amp;#34;Adding 212 to 384:&amp;#34;&lt;/span&gt;, add2x(&lt;span style="color:#ae81ff"&gt;212&lt;/span&gt;, &lt;span style="color:#ae81ff"&gt;384&lt;/span&gt;))
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;print(&lt;span style="color:#e6db74"&gt;&amp;#34;Multiplying 212 by 384:&amp;#34;&lt;/span&gt;, mul2x(&lt;span style="color:#ae81ff"&gt;212&lt;/span&gt;, &lt;span style="color:#ae81ff"&gt;384&lt;/span&gt;))
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;You should also verify that incorrect input is handled properly.&lt;/p&gt;
&lt;p&gt;For example:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"&gt;&lt;code class="language-python" data-lang="python"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;print(mul2x(&lt;span style="color:#ae81ff"&gt;212&lt;/span&gt;, &lt;span style="color:#e6db74"&gt;&amp;#34;A tester walks into a bar&amp;#34;&lt;/span&gt;))
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;or:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"&gt;&lt;code class="language-python" data-lang="python"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;print(mul2x(&lt;span style="color:#ae81ff"&gt;212&lt;/span&gt;, &lt;span style="color:#ae81ff"&gt;384&lt;/span&gt;, &lt;span style="color:#ae81ff"&gt;25&lt;/span&gt;))
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;Both cases should result in Python exceptions being raised by the argument validation code.&lt;/p&gt;
&lt;h2 id="final-thoughts"&gt;Final Thoughts
&lt;/h2&gt;&lt;p&gt;Keep your spirits up.&lt;/p&gt;
&lt;p&gt;Rome wasn&amp;rsquo;t built in a day.&lt;/p&gt;
&lt;p&gt;Neither are C libraries, Python bindings, build systems, or debugging skills.&lt;/p&gt;
&lt;p&gt;Compilation errors, broken builds, failed tests, and nights spent chasing mysterious bugs are simply part of the profession.&lt;/p&gt;
&lt;p&gt;The important thing is to remember that every experienced developer has been through exactly the same process.&lt;/p&gt;
&lt;p&gt;Some of them are still going through it.&lt;/p&gt;</description></item></channel></rss>