| 
									
										
										
										
											2002-04-05 19:54:19 +00:00
										 |  |  | \chapter{Building C and \Cpp{} Extensions on Windows%
 | 
					
						
							| 
									
										
										
										
											2001-08-20 19:30:29 +00:00
										 |  |  |      \label{building-on-windows}} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | This chapter briefly explains how to create a Windows extension module | 
					
						
							| 
									
										
										
										
											2001-11-28 07:26:15 +00:00
										 |  |  | for Python using Microsoft Visual \Cpp, and follows with more | 
					
						
							| 
									
										
										
										
											2001-08-20 19:30:29 +00:00
										 |  |  | detailed background information on how it works.  The explanatory | 
					
						
							|  |  |  | material is useful for both the Windows programmer learning to build | 
					
						
							|  |  |  | Python extensions and the \UNIX{} programmer interested in producing | 
					
						
							|  |  |  | software which can be successfully built on both \UNIX{} and Windows. | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2002-03-09 10:06:14 +00:00
										 |  |  | Module authors are encouraged to use the distutils approach for | 
					
						
							|  |  |  | building extension modules, instead of the one described in this | 
					
						
							|  |  |  | section. You will still need the C compiler that was used to build | 
					
						
							|  |  |  | Python; typically Microsoft Visual \Cpp. | 
					
						
							| 
									
										
										
										
											2001-08-20 19:30:29 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2002-04-19 04:04:57 +00:00
										 |  |  | \begin{notice} | 
					
						
							|  |  |  |   This chapter mentions a number of filenames that include an encoded | 
					
						
							|  |  |  |   Python version number.  These filenames are represented with the | 
					
						
							|  |  |  |   version number shown as \samp{XY}; in practive, \character{X} will | 
					
						
							|  |  |  |   be the major version number and \character{Y} will be the minor | 
					
						
							|  |  |  |   version number of the Python release you're working with.  For | 
					
						
							|  |  |  |   example, if you are using Python 2.2.1, \samp{XY} will actually be | 
					
						
							|  |  |  |   \samp{22}. | 
					
						
							|  |  |  | \end{notice} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2001-08-20 19:30:29 +00:00
										 |  |  | \section{A Cookbook Approach \label{win-cookbook}} | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2001-12-13 17:20:32 +00:00
										 |  |  | There are two approaches to building extension modules on Windows, | 
					
						
							|  |  |  | just as there are on \UNIX: use the \refmodule{distutils} package to | 
					
						
							|  |  |  | control the build process, or do things manually.  The distutils | 
					
						
							|  |  |  | approach works well for most extensions; documentation on using | 
					
						
							|  |  |  | \refmodule{distutils} to build and package extension modules is | 
					
						
							|  |  |  | available in \citetitle[../dist/dist.html]{Distributing Python | 
					
						
							|  |  |  | Modules}.  This section describes the manual approach to building | 
					
						
							|  |  |  | Python extensions written in C or \Cpp. | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | To build extensions using these instructions, you need to have a copy | 
					
						
							|  |  |  | of the Python sources of the same version as your installed Python. | 
					
						
							|  |  |  | You will need Microsoft Visual \Cpp{} ``Developer Studio''; project | 
					
						
							|  |  |  | files are supplied for V\Cpp{} version 6, but you can use older | 
					
						
							|  |  |  | versions of V\Cpp.  The example files described here are distributed | 
					
						
							|  |  |  | with the Python sources in the \file{PC\textbackslash | 
					
						
							|  |  |  | example_nt\textbackslash} directory. | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | \begin{enumerate} | 
					
						
							|  |  |  |   \item | 
					
						
							|  |  |  |   \strong{Copy the example files}\\ | 
					
						
							|  |  |  |     The \file{example_nt} directory is a subdirectory of the \file{PC} | 
					
						
							|  |  |  |     directory, in order to keep all the PC-specific files under the | 
					
						
							|  |  |  |     same directory in the source distribution.  However, the | 
					
						
							|  |  |  |     \file{example_nt} directory can't actually be used from this | 
					
						
							|  |  |  |     location.  You first need to copy or move it up one level, so that | 
					
						
							|  |  |  |     \file{example_nt} is a sibling of the \file{PC} and \file{Include} | 
					
						
							|  |  |  |     directories.  Do all your work from within this new location. | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   \item | 
					
						
							|  |  |  |   \strong{Open the project}\\ | 
					
						
							|  |  |  |     From V\Cpp, use the \menuselection{File \sub Open Workspace} | 
					
						
							|  |  |  |     dialog (not \menuselection{File \sub Open}!).  Navigate to and | 
					
						
							|  |  |  |     select the file \file{example.dsw}, in the \emph{copy} of the | 
					
						
							|  |  |  |     \file{example_nt} directory you made above.  Click Open. | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   \item | 
					
						
							|  |  |  |   \strong{Build the example DLL}\\ | 
					
						
							|  |  |  |     In order to check that everything is set up right, try building: | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     \begin{enumerate} | 
					
						
							|  |  |  |       \item | 
					
						
							|  |  |  |         Select a configuration.  This step is optional.  Choose | 
					
						
							|  |  |  |         \menuselection{Build \sub Select Active Configuration} and | 
					
						
							|  |  |  |         select either ``example - Win32 Release'' or ``example - Win32 | 
					
						
							|  |  |  |         Debug.''  If you skip this step, V\Cpp{} will use the Debug | 
					
						
							|  |  |  |         configuration by default. | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |       \item | 
					
						
							|  |  |  |         Build the DLL.  Choose \menuselection{Build \sub Build | 
					
						
							|  |  |  |         example_d.dll} in Debug mode, or \menuselection{Build \sub | 
					
						
							|  |  |  |         Build example.dll} in Release mode.  This creates all | 
					
						
							|  |  |  |         intermediate and result files in a subdirectory called either | 
					
						
							|  |  |  |         \file{Debug} or \file{Release}, depending on which | 
					
						
							|  |  |  |         configuration you selected in the preceding step. | 
					
						
							|  |  |  |     \end{enumerate} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   \item | 
					
						
							|  |  |  |   \strong{Testing the debug-mode DLL}\\ | 
					
						
							|  |  |  |     Once the Debug build has succeeded, bring up a DOS box, and change | 
					
						
							|  |  |  |     to the \file{example_nt\textbackslash Debug} directory.  You | 
					
						
							|  |  |  |     should now be able to repeat the following session (\code{C>} is | 
					
						
							|  |  |  |     the DOS prompt, \code{>\code{>}>} is the Python prompt; note that | 
					
						
							|  |  |  |     build information and various debug output from Python may not | 
					
						
							|  |  |  |     match this screen dump exactly): | 
					
						
							| 
									
										
										
										
											2001-08-20 19:30:29 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2001-12-13 17:20:32 +00:00
										 |  |  | \begin{verbatim} | 
					
						
							|  |  |  | C>..\..\PCbuild\python_d | 
					
						
							|  |  |  | Adding parser accelerators ... | 
					
						
							|  |  |  | Done. | 
					
						
							|  |  |  | Python 2.2 (#28, Dec 19 2001, 23:26:37) [MSC 32 bit (Intel)] on win32 | 
					
						
							|  |  |  | Type "copyright", "credits" or "license" for more information. | 
					
						
							|  |  |  | >>> import example | 
					
						
							|  |  |  | [4897 refs] | 
					
						
							|  |  |  | >>> example.foo() | 
					
						
							|  |  |  | Hello, world | 
					
						
							|  |  |  | [4903 refs] | 
					
						
							|  |  |  | >>> | 
					
						
							|  |  |  | \end{verbatim} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     Congratulations!  You've successfully built your first Python | 
					
						
							|  |  |  |     extension module. | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   \item | 
					
						
							| 
									
										
										
										
											2002-07-04 08:36:53 +00:00
										 |  |  |   \strong{Creating your own project}\\ | 
					
						
							| 
									
										
										
										
											2001-12-13 17:20:32 +00:00
										 |  |  |     Choose a name and create a directory for it.  Copy your C sources | 
					
						
							|  |  |  |     into it.  Note that the module source file name does not | 
					
						
							|  |  |  |     necessarily have to match the module name, but the name of the | 
					
						
							|  |  |  |     initialization function should match the module name --- you can | 
					
						
							|  |  |  |     only import a module \module{spam} if its initialization function | 
					
						
							|  |  |  |     is called \cfunction{initspam()}, and it should call | 
					
						
							|  |  |  |     \cfunction{Py_InitModule()} with the string \code{"spam"} as its | 
					
						
							|  |  |  |     first argument (use the minimal \file{example.c} in this directory | 
					
						
							|  |  |  |     as a guide).  By convention, it lives in a file called | 
					
						
							|  |  |  |     \file{spam.c} or \file{spammodule.c}.  The output file should be | 
					
						
							|  |  |  |     called \file{spam.dll} or \file{spam.pyd} (the latter is supported | 
					
						
							|  |  |  |     to avoid confusion with a system library \file{spam.dll} to which | 
					
						
							|  |  |  |     your module could be a Python interface) in Release mode, or | 
					
						
							|  |  |  |     \file{spam_d.dll} or \file{spam_d.pyd} in Debug mode. | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     Now your options are: | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     \begin{enumerate} | 
					
						
							|  |  |  |       \item  Copy \file{example.dsw} and \file{example.dsp}, rename | 
					
						
							|  |  |  |              them to \file{spam.*}, and edit them by hand, or | 
					
						
							|  |  |  |       \item  Create a brand new project; instructions are below. | 
					
						
							|  |  |  |     \end{enumerate} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     In either case, copy \file{example_nt\textbackslash example.def} | 
					
						
							|  |  |  |     to \file{spam\textbackslash spam.def}, and edit the new | 
					
						
							|  |  |  |     \file{spam.def} so its second line contains the string | 
					
						
							|  |  |  |     `\code{initspam}'.  If you created a new project yourself, add the | 
					
						
							|  |  |  |     file \file{spam.def} to the project now.  (This is an annoying | 
					
						
							|  |  |  |     little file with only two lines.  An alternative approach is to | 
					
						
							|  |  |  |     forget about the \file{.def} file, and add the option | 
					
						
							|  |  |  |     \programopt{/export:initspam} somewhere to the Link settings, by | 
					
						
							|  |  |  |     manually editing the setting in Project Options dialog). | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   \item | 
					
						
							|  |  |  |   \strong{Creating a brand new project}\\ | 
					
						
							|  |  |  |     Use the \menuselection{File \sub New \sub Projects} dialog to | 
					
						
							|  |  |  |     create a new Project Workspace.  Select ``Win32 Dynamic-Link | 
					
						
							|  |  |  |     Library,'' enter the name (\samp{spam}), and make sure the | 
					
						
							|  |  |  |     Location is set to the \file{spam} directory you have created | 
					
						
							|  |  |  |     (which should be a direct subdirectory of the Python build tree, a | 
					
						
							|  |  |  |     sibling of \file{Include} and \file{PC}).  Select Win32 as the | 
					
						
							|  |  |  |     platform (in my version, this is the only choice).  Make sure the | 
					
						
							|  |  |  |     Create new workspace radio button is selected.  Click OK. | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     Now open the \menuselection{Project \sub Settings} dialog.  You | 
					
						
							|  |  |  |     only need to change a few settings.  Make sure All Configurations | 
					
						
							|  |  |  |     is selected from the Settings for: dropdown list.  Select the | 
					
						
							|  |  |  |     C/\Cpp{} tab.  Choose the Preprocessor category in the popup menu | 
					
						
							|  |  |  |     at the top.  Type the following text in the entry box labeled | 
					
						
							|  |  |  |     Addditional include directories: | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | \begin{verbatim} | 
					
						
							|  |  |  | ..\Include,..\PC | 
					
						
							|  |  |  | \end{verbatim} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     Then, choose the Input category in the Link tab, and enter | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | \begin{verbatim} | 
					
						
							|  |  |  | ..\PCbuild | 
					
						
							|  |  |  | \end{verbatim} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     in the text box labelled ``Additional library path.'' | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     Now you need to add some mode-specific settings: | 
					
						
							| 
									
										
										
										
											2001-08-20 19:30:29 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2001-12-13 17:20:32 +00:00
										 |  |  |     Select ``Win32 Release'' in the ``Settings for'' dropdown list. | 
					
						
							|  |  |  |     Click the Link tab, choose the Input Category, and append | 
					
						
							| 
									
										
										
										
											2002-04-19 04:04:57 +00:00
										 |  |  |     \code{pythonXY.lib} to the list in the ``Object/library modules'' | 
					
						
							| 
									
										
										
										
											2001-12-13 17:20:32 +00:00
										 |  |  |     box. | 
					
						
							| 
									
										
										
										
											2001-08-20 19:30:29 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2001-12-13 17:20:32 +00:00
										 |  |  |     Select ``Win32 Debug'' in the ``Settings for'' dropdown list, and | 
					
						
							| 
									
										
										
										
											2002-04-19 04:04:57 +00:00
										 |  |  |     append \code{pythonXY_d.lib} to the list in the ``Object/library | 
					
						
							| 
									
										
										
										
											2001-12-13 17:20:32 +00:00
										 |  |  |     modules'' box.  Then click the C/\Cpp{} tab, select ``Code | 
					
						
							|  |  |  |     Generation'' from the Category dropdown list, and select ``Debug | 
					
						
							|  |  |  |     Multithreaded DLL'' from the ``Use run-time library'' dropdown | 
					
						
							|  |  |  |     list. | 
					
						
							| 
									
										
										
										
											2001-08-20 19:30:29 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2001-12-13 17:20:32 +00:00
										 |  |  |     Select ``Win32 Release'' again from the ``Settings for'' dropdown | 
					
						
							|  |  |  |     list.  Select ``Multithreaded DLL'' from the ``Use run-time | 
					
						
							|  |  |  |     library:'' dropdown list. | 
					
						
							| 
									
										
										
										
											2001-08-20 19:30:29 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2002-11-05 16:52:50 +00:00
										 |  |  |     You should now create the file \file{spam.def} as instructed in the | 
					
						
							| 
									
										
										
										
											2001-12-13 17:20:32 +00:00
										 |  |  |     previous section.  Then chose the \menuselection{Insert \sub Files | 
					
						
							|  |  |  |     into Project} dialog.  Set the pattern to \code{*.*} and select | 
					
						
							|  |  |  |     both \file{spam.c} and \file{spam.def} and click OK.  (Inserting | 
					
						
							|  |  |  |     them one by one is fine too.) | 
					
						
							|  |  |  | \end{enumerate} | 
					
						
							| 
									
										
										
										
											2001-08-20 19:30:29 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | If your module creates a new type, you may have trouble with this line: | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | \begin{verbatim} | 
					
						
							|  |  |  |     PyObject_HEAD_INIT(&PyType_Type) | 
					
						
							|  |  |  | \end{verbatim} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | Change it to: | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | \begin{verbatim} | 
					
						
							|  |  |  |     PyObject_HEAD_INIT(NULL) | 
					
						
							|  |  |  | \end{verbatim} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | and add the following to the module initialization function: | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | \begin{verbatim} | 
					
						
							|  |  |  |     MyObject_Type.ob_type = &PyType_Type; | 
					
						
							|  |  |  | \end{verbatim} | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2002-11-05 16:52:50 +00:00
										 |  |  | Refer to section~3 of the | 
					
						
							| 
									
										
										
										
											2001-08-20 19:30:29 +00:00
										 |  |  | \citetitle[http://www.python.org/doc/FAQ.html]{Python FAQ} for details | 
					
						
							|  |  |  | on why you must do this. | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | \section{Differences Between \UNIX{} and Windows | 
					
						
							|  |  |  |      \label{dynamic-linking}} | 
					
						
							|  |  |  | \sectionauthor{Chris Phoenix}{cphoenix@best.com} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | \UNIX{} and Windows use completely different paradigms for run-time | 
					
						
							|  |  |  | loading of code.  Before you try to build a module that can be | 
					
						
							|  |  |  | dynamically loaded, be aware of how your system works. | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2001-11-28 07:26:15 +00:00
										 |  |  | In \UNIX, a shared object (\file{.so}) file contains code to be used by the | 
					
						
							| 
									
										
										
										
											2001-08-20 19:30:29 +00:00
										 |  |  | program, and also the names of functions and data that it expects to | 
					
						
							|  |  |  | find in the program.  When the file is joined to the program, all | 
					
						
							|  |  |  | references to those functions and data in the file's code are changed | 
					
						
							|  |  |  | to point to the actual locations in the program where the functions | 
					
						
							|  |  |  | and data are placed in memory.  This is basically a link operation. | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | In Windows, a dynamic-link library (\file{.dll}) file has no dangling | 
					
						
							|  |  |  | references.  Instead, an access to functions or data goes through a | 
					
						
							|  |  |  | lookup table.  So the DLL code does not have to be fixed up at runtime | 
					
						
							|  |  |  | to refer to the program's memory; instead, the code already uses the | 
					
						
							|  |  |  | DLL's lookup table, and the lookup table is modified at runtime to | 
					
						
							|  |  |  | point to the functions and data. | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2001-11-28 07:26:15 +00:00
										 |  |  | In \UNIX, there is only one type of library file (\file{.a}) which | 
					
						
							| 
									
										
										
										
											2001-08-20 19:30:29 +00:00
										 |  |  | contains code from several object files (\file{.o}).  During the link | 
					
						
							|  |  |  | step to create a shared object file (\file{.so}), the linker may find | 
					
						
							|  |  |  | that it doesn't know where an identifier is defined.  The linker will | 
					
						
							|  |  |  | look for it in the object files in the libraries; if it finds it, it | 
					
						
							|  |  |  | will include all the code from that object file. | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | In Windows, there are two types of library, a static library and an | 
					
						
							|  |  |  | import library (both called \file{.lib}).  A static library is like a | 
					
						
							|  |  |  | \UNIX{} \file{.a} file; it contains code to be included as necessary. | 
					
						
							|  |  |  | An import library is basically used only to reassure the linker that a | 
					
						
							|  |  |  | certain identifier is legal, and will be present in the program when | 
					
						
							|  |  |  | the DLL is loaded.  So the linker uses the information from the | 
					
						
							|  |  |  | import library to build the lookup table for using identifiers that | 
					
						
							|  |  |  | are not included in the DLL.  When an application or a DLL is linked, | 
					
						
							|  |  |  | an import library may be generated, which will need to be used for all | 
					
						
							|  |  |  | future DLLs that depend on the symbols in the application or DLL. | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | Suppose you are building two dynamic-load modules, B and C, which should | 
					
						
							| 
									
										
										
										
											2001-11-28 07:26:15 +00:00
										 |  |  | share another block of code A.  On \UNIX, you would \emph{not} pass | 
					
						
							| 
									
										
										
										
											2001-08-20 19:30:29 +00:00
										 |  |  | \file{A.a} to the linker for \file{B.so} and \file{C.so}; that would | 
					
						
							|  |  |  | cause it to be included twice, so that B and C would each have their | 
					
						
							|  |  |  | own copy.  In Windows, building \file{A.dll} will also build | 
					
						
							|  |  |  | \file{A.lib}.  You \emph{do} pass \file{A.lib} to the linker for B and | 
					
						
							|  |  |  | C.  \file{A.lib} does not contain code; it just contains information | 
					
						
							|  |  |  | which will be used at runtime to access A's code.   | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | In Windows, using an import library is sort of like using \samp{import | 
					
						
							|  |  |  | spam}; it gives you access to spam's names, but does not create a | 
					
						
							| 
									
										
										
										
											2001-11-28 07:26:15 +00:00
										 |  |  | separate copy.  On \UNIX, linking with a library is more like | 
					
						
							| 
									
										
										
										
											2001-08-20 19:30:29 +00:00
										 |  |  | \samp{from spam import *}; it does create a separate copy. | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | \section{Using DLLs in Practice \label{win-dlls}} | 
					
						
							|  |  |  | \sectionauthor{Chris Phoenix}{cphoenix@best.com} | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2001-11-28 07:26:15 +00:00
										 |  |  | Windows Python is built in Microsoft Visual \Cpp; using other | 
					
						
							| 
									
										
										
										
											2001-08-20 19:30:29 +00:00
										 |  |  | compilers may or may not work (though Borland seems to).  The rest of | 
					
						
							|  |  |  | this section is MSV\Cpp{} specific. | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2002-04-19 04:04:57 +00:00
										 |  |  | When creating DLLs in Windows, you must pass \file{pythonXY.lib} to | 
					
						
							| 
									
										
										
										
											2001-08-20 19:30:29 +00:00
										 |  |  | the linker.  To build two DLLs, spam and ni (which uses C functions | 
					
						
							|  |  |  | found in spam), you could use these commands: | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | \begin{verbatim} | 
					
						
							| 
									
										
										
										
											2002-04-19 04:04:57 +00:00
										 |  |  | cl /LD /I/python/include spam.c ../libs/pythonXY.lib | 
					
						
							|  |  |  | cl /LD /I/python/include ni.c spam.lib ../libs/pythonXY.lib | 
					
						
							| 
									
										
										
										
											2001-08-20 19:30:29 +00:00
										 |  |  | \end{verbatim} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | The first command created three files: \file{spam.obj}, | 
					
						
							|  |  |  | \file{spam.dll} and \file{spam.lib}.  \file{Spam.dll} does not contain | 
					
						
							|  |  |  | any Python functions (such as \cfunction{PyArg_ParseTuple()}), but it | 
					
						
							| 
									
										
										
										
											2002-04-19 04:04:57 +00:00
										 |  |  | does know how to find the Python code thanks to \file{pythonXY.lib}. | 
					
						
							| 
									
										
										
										
											2001-08-20 19:30:29 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  | The second command created \file{ni.dll} (and \file{.obj} and | 
					
						
							|  |  |  | \file{.lib}), which knows how to find the necessary functions from | 
					
						
							|  |  |  | spam, and also from the Python executable. | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | Not every identifier is exported to the lookup table.  If you want any | 
					
						
							|  |  |  | other modules (including Python) to be able to see your identifiers, | 
					
						
							|  |  |  | you have to say \samp{_declspec(dllexport)}, as in \samp{void | 
					
						
							|  |  |  | _declspec(dllexport) initspam(void)} or \samp{PyObject | 
					
						
							|  |  |  | _declspec(dllexport) *NiGetSpamData(void)}. | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | Developer Studio will throw in a lot of import libraries that you do | 
					
						
							|  |  |  | not really need, adding about 100K to your executable.  To get rid of | 
					
						
							|  |  |  | them, use the Project Settings dialog, Link tab, to specify | 
					
						
							|  |  |  | \emph{ignore default libraries}.  Add the correct | 
					
						
							|  |  |  | \file{msvcrt\var{xx}.lib} to the list of libraries. |