CREATING PYTHON EXTENSIONS
USING BORLAND'S FREE COMPILER
This paper describes the method used to create Python Extensions using the Borland 5.5 C++ Compiler (BCC). This command line compiler is available free from http://www.borland.com/bcppbuilder/freecompiler/. In the sections below, I describe the steps that are necessary to produce the extension from the C source code and how to set up the associated files for the compiler and linker. These extensions work with the standard Windows distribution of Python. The process used to produce the extension is very easy and consists of running a simple batch file that I have provided as part of this package. I also have a short reference section at the end of this paper that may be helpful.
When I first wanted to use BCC to create Python Extensions, I asked on the comp.lang.python news group if anyone knew how to do this. From the few responses that I got back, there appeared to be people interested, but no one knew how as there are compatibility issues between MSVC and BCC. After struggling a lot (I had never compiled a C program before I started on this) these problems have been overcome. I am now sharing this information with you.
Version 2.0 adds a patch to the config.h file and provides another example. If you feel that I have left something out, please contact me at g_will@cyberus.ca
Gordon Williams, July 7, 2000
Note:
STEPS
The steps outlined below are based on W95. If you are using another Window OS, you will have to modify it a bit.
Setting Up the Compiler
Here are the steps that you need to follow to set up BCC.
- The core C++Builder Help file (BCB5.HLP),
- Standard C++ Library Help (BCB5SCL.HLP),
- C++Builder Language Guide Help (BCB5LANG.HLP),
- The C Runtime Library Reference (BCB5RTL.HLP), and
- The Errors Messages and Warnings listing (BCB5ERRS.HLP).
All of these files (and more!) are available for free download from the Borland C++Builder documentation site at http:\\www.borland.com\techpubs\bcppbuilder. If you are doing some difficult things, you may want Turbo Debugger as well.
The bcc32.cfg file is:
-w
-I"E:\BORLAND\BCC55\INCLUDE;.\;E:\PROGRAM FILES\PYTHON\INCLUDE"
-L"E:\BORLAND\BCC55\LIB;e:\Borland\Bcc55\lib\psdk;E:\PROGRAM FILES\PYTHON\LIBS"
You will need to substitute the correct path to the BCC and Python INCLUDE directories as well as the BCC LIB and Python LIBS directories.
The ilink32.cfg is:
-x
-L"E:\BORLAND\BCC55\LIB;e:\Borland\bcc55\lib\psdk;E:\PROGRAM FILES\PYTHON\LIBS"
Likewise, you will have to change the paths so they match yours.
rem for borland c compiller
PATH=E:\BORLAND\BCC55\BIN;%PATH%
#endif /* BORLANDC */
/* Added patch section for Borland Compiler to produce
extensions using the Microsoft binary distribution core */
#ifdef MSC_CORE_BC_EXT
#define DL_IMPORT(RTYPE) __declspec(dllimport) RTYPE
#define DL_EXPORT(RTYPE) __declspec(dllexport) RTYPE
#endif
/* End of added patch section */
/* End of compilers - finish up */
Note the first and last lines above already exist. (Thanks to Ng Pheng Siong <ngps@post1.com> who provided this patch. He provides an explanation here.)
That is all there is to the setup of the compiler.
Making it all Happen
Now that you have done the difficult part, here are the files that you need to make it all work.
__declspec(dllexport)
void initmodulename()
to export the initmodulename for module initialization.
As noted above, BCC puts underscores on the exported name. Therefore, to rectify this the modulename.def should contain:
EXPORTS
initmodulename=_initmodulename
The left hand side must start with init followed by the name of the extension as this is what Python expects.
Static RTL Linking
bcc32 -c -tWM -DMSC_CORE_BC_EXT example.c
ilink32 -Tpd example c0d32,example.pyd,,mypylib import32 cw32mt,example
Dynamic RTL Linking
bcc32 -c -tWM -tWR -DMSC_CORE_BC_EXT example.c
ilink32 -Tpd example c0d32,example.pyd,,mypylib import32 cw32mti,example
In both the above the module name is example.pyd. The difference between the static and dynamic linking is the extension size and the fact that you need to distribute cc3250mt.dll with your .pyd when it is dynamically linked. Most of the time I think that you will want to link it statically and not distribute the rather large cc3250mt.dll.
TEST EXAMPLES
I have included a bunch of examples that you can try out once you have your compiler set up. One has both a static and a dynamic version so you can make the comparison your self. If you have set everything up correctly, go to the example directory and run the .bat file. The .pyd file will appear after a few seconds. Import the module into python and try it out.
This example is from Quick Python. It is statically linked to the RTL. It takes two integers and adds or multiplies them. For example:
E:\Borland\MYSOURCE\pyExtension\ExTest1_Stat>python
Python 1.5.2 (#0, Apr 13 1999, 10:51:12) [MSC 32 bit (Intel)] on win32
Copyright 1991-1995 Stichting Mathematisch Centrum, Amsterdam
>>> import example
>>> example.add(2,3)
5
>>> example.mult(3,6)
18
>>>
This example is from Quick Python. It has both a statically linked and dynamically linked version. It takes a single Python object as an argument, and returns a two-element Python list, with each consisting of a reference to the object past in as an argument. Memory management using Py_INCREF is used. As an example:
E:\Borland\MYSOURCE\pyExtension\ExTest2_Stat>python
Python 1.5.2 (#0, Apr 13 1999, 10:51:12) [MSC 32 bit (Intel)] on win32
Copyright 1991-1995 Stichting Mathematisch Centrum, Amsterdam
>>> import example
>>> example.makelist([1,2,(5,6,7),"abc"])
[[1, 2, (5, 6, 7), 'abc'], [1, 2, (5, 6, 7), 'abc']]
>>>
This example comes from the Python Extending/Embedding Manual. It is also shown in Python Programming on Win32. This creates a module called spam and exposes a function called system(), which runs a DOS command. After importing spam, if you type spam.system("start notepad") you will see the notepad appear on your screen.
This example shows module and function doc strings as well as how to create an exception. A "None" return value is also created in a number of different ways.
>>> import example
>>> example.__doc__
'This module contains a bunch of stuff for an example'
>>> example.add.__doc__
'This function adds two ints'
>>> dir(example)
['__doc__', '__file__', '__name__', 'add', 'error', 'myExcept', 'returnNone1', 'returnNone2', 'returnNone3', 'returnNone4']
>>> example.myExcept()
Traceback (innermost last):
File "<interactive input>", line 0, in ?
error: Made an error and caused exception
>>> example.returnNone4()
(None, None, None)
REFERENCES AND OTHER INFORMATION
1. BCC Compiler/Linker/Tools Information - Use the downloaded online help files.
2. BCC Compiler/Linker/Tools NewsGroups through link on http://www.borland.com/bcppbuilder/freecompiler/
3. Michael P. Reilly's "How to write a Python Extension" at http://starship.python.net/~arcege/extwriting/pyext.html
4. Python Extending/Embedding Manual - Part of the standard Python Documents
5. Hammond and Robinson, "Python Programming on Win32" - Good on how to use MSVC to make an extension but weak on how to write and extension. Lots of good information about Win32 programming.
6. Harms and McDonald, "The Quick Python Book" - Better on how to write an extension. Good info about general Python Programming.
7. Do your own Web Search.
Copyright (C) Gordon C. Williams, May , 2000
Version 2.0