Native Python extensions for Blender with Visual Studio 2013

Researching how to create a python module in C with Microsoft Visual Studio 2013 which could be used in Blender caused me quite a few headaches so in order to spare other people the same I wrote this article that illustrates the process in a step-by-step manner. The resulting solution is available on GitHub as well.

Prerequisites

When writing native extensions for Python it is said that it is vitally important to use exactly the same compiler that was used to compiler Blender itself (or rather its embedded Python). This is especially important on Windows where even different versions of Visual Studio may break compatibility. However, I have found that Visual Studio 2013 can be used to compile an extension that is usable both for Blender version compiled with msvc2008 and msvc2013.

Currently the daily builds for Blender are built with Visual Studio 2013. This can be verified by opening Blender and generating the system information from Help -> System Info. In the generated text file (available in the text editor) the line with the Python version should read something like: ...... 1800 64 bit .... The 1800 part is the interesting bit as it identifues the version of Visual Studio, where 1800 means MSVC 2013.

The official Blendet 2.70 release for windows is still built with MSVC 2008 (the version string in the system info will show 1500) but I have found no compatibility issues, but of course your mileage may vary. It is however extremely important to match the platform: a 64 bit extension will only work for 64 bit Blender!

Writing an extension module in C

Starting point when writing an extension is this page. It's a fairly complete but lengthy introduction and its content is platform independent. To actually compile C code into a dynamic library that can be used on Windows additional information is needed. Unfortunately some information on this page is wrong or incomplete (/export:initexample is not needed, the dll needs a .pyd extension) and as there are quite a few confusing steps it might be easier to have all the steps explicitely listed for our Blender scenario.

In the following walkthrough I'll assume that Blender is installed in C:\Blender and that we'll be using MVSC 2013 express edition for Desktop. I also assume you have checked out the Python library that Blender is built with, to C:\BlenderLibraries. We need the source for these libraries for the Python.h include files. (you can checkout these libraries with any subversion client from svn.blender.org, see here for instructions. Make sure you get the 64 bit versions if you are compiling for a 64 bit platform and notice that the folder is called win64_vc12 even though we'll be using msvc 2013)

Ten easy steps

The following steps are needed to create a simple extension. each step is explained in detail below.

  1. Create a new DLL project
  2. Add a new x64 platform if necessary
  3. Configure the extension to use
  4. Configure the include directory
  5. Configure the library directory
  6. Add the library dependencies
  7. Add your source code
  8. Build the project
  9. Copy the library to the Blender installation
  10. Test it from Blender

Create a new DLL project

  • file->new project
  • templates->Visual C++->Win32->Win32 Project
  • name: BlenderTest (can be placed anywhere, leave all default settings)
In the application wizard that opens select DLL and Empty project.

Add a new x64 platform if necessary

i=If you are working on/for a 64-bit platform you'll need to add a x64 platform to your solution.

  • click on the configuration manager [below the menu bar in the task bar]
  • add a new active platform [click on the part that probably displays Win32]
  • select x64 and leave all the default settings

Configure the extension to use

Although a native extension is just a DLL, Python wants it to have a .pyd extension:
In the properties of the BlenderTest project
for all configurations set
Configuration properties -> General the Target extension to .pyd

Configure the include directory

The compiler needs to be able to find the Python.h include file.
for all configurations
Configuration properties -> C/C++ -> General Add 'C:\BlenderLibraries\win64_vc12\python\include\python3.3' to Additional Include directories

Configure the library directory

The Python libraries need to found as well:
for all configurations
Configuration properties -> Linker -> General Add 'C:\BlenderLibraries\win64_vc12\python\lib' to Additional Library directories

Add the library dependencies

Each configuration is dependent on a different library:
for the Debug configuration
Linker -> Input Add 'python33_d.lib' to Additional Dependencies
for the Release configuration
Linker -> Input Add 'python33.lib' to Additional Dependencies

Add your source code

in the Solution explorer, right click the Source Files folder in the BlenderTest project and slect add -> new item. Choose C++ file and give it BlenderTest.cpp as its name (although you're free to choose anything you want)

Copy the example code (you might want to use this) in the editor

build the solution (a warning about an inconsistent dll linkage of round can be ignored)

Build the project

Select the release configuration and click Build -> Build Solution

The module will be in the subfolder BlenderTest\x64\Release and be called BlenderTest.pyd

Copy the library to the Blender installation

Copy BlenderTest.pyd to somewhere where Blender can find it, for example to the site-packages directory within Blenders installation directory (e.g. C:\Blender\2.70\python\lib\site-packages)

Test it from Blender

open the python console in Blender
import BlenderTest
BlenderTest.foo()

The System console (Window -> toggle system console) should show 'Hello World'

No comments:

Post a Comment