15

I have got some code written in c++ which i am trying to use in python without rewriting the complete code in python again and i am using Pybind11 to build a python module for that. I am trying to achieve this thing in Microsoft Visual Studio 2015 by following this tutorial here https://pybind11.readthedocs.io/en/stable/basics.html

I did following things in visual studio. 1) Downloaded Pybind11 from https://codeload.github.com/pybind/pybind11/zip/master

2) Unzipped the file

3) In visual studio a started a new empty C++ project.

4) Added my python interpreter include folder ( C:/python27/include) and Pybind11( C:/Pybind11/include) in VC++ directories > include directories

5) Added additional dependencies (C:\Python27\libs\python27.lib) in Linker>input>Additional dependencies

6) To use the output file in Python i need a .pyd file so i modified here Configuration Properties>General>Target extension : .pyd

7) Change project defaults > configuration type to Dynamic Library (.dll)

So i am able to build my project and generate the .pyd file but when importing this module i am getting following error: ImportError: dynamic module does not define init function (initProject11)

I searched for this error and got this link http://pybind11.readthedocs.io/en/stable/faq.html but i could not find my solution.

So i am looking for the solution for above problem. Thanks a lot in advance.

here is my CPP file code

#include <pybind11/pybind11.h>

int add(int i, int j) {
return i + j;
}

namespace py = pybind11;

PYBIND11_PLUGIN(example) {
    py::module m("example", "pybind11 example plugin");

    m.def("add", &add, "A function which adds two numbers");

    return m.ptr();
}
flamelite
  • 2,654
  • 3
  • 22
  • 42
  • 1
    Did you leave the C++ project empty? Or did you add any python modules using something like `PYBIND11_PLUGIN(...) {...}`. – pschill Jul 12 '17 at 10:19
  • 1
    I don't use Pybind, but generally, it seems that your init function name and your module (file) name do not match. – YiFei Jul 12 '17 at 10:21
  • 1
    No, i wrote the most basic code in C++ – flamelite Jul 12 '17 at 10:24
  • 1
    @YiFei can you explain me a little about where is init function used? – flamelite Jul 12 '17 at 10:28
  • 1
    What is the name of the generated .pyd file? It should match the module name, so something like `example.pyd` or `example.*.pyd`. – pschill Jul 12 '17 at 10:29
  • 1
    Project11.pyd same as my project name – flamelite Jul 12 '17 at 10:31
  • 1
    Can you rename the file to `example.pyd` and see if that works? – pschill Jul 12 '17 at 10:31
  • 1
    i did that at Configuration properties>general>target name : $(example) – flamelite Jul 12 '17 at 10:36
  • 1
    but i got this error: TargetPath(..\visual studio 2015\Projects\Project11\x64\Debug\.pyd) does not match the Linker's OutputFile property value – flamelite Jul 12 '17 at 10:37
  • 1
    Then you may need to change _Configuration Properties > Linker > Output File_ as well. Or just take the `Project11.pyd` that was produced before, rename it to `example.pyd`, and then import it in python. – pschill Jul 12 '17 at 10:38
  • 1
    I modified that as $(OutDir)$(example)$(TargetExt) but now i am getting a .pyd file with no name – flamelite Jul 12 '17 at 10:42

1 Answers1

12

In python, the name of the .pyd file must be the same as the module that is inside. From the documentation (https://docs.python.org/2/faq/windows.html):

If you have a DLL named foo.pyd, then it must have a function initfoo(). You can then write Python “import foo”, and Python will search for foo.pyd (as well as foo.py, foo.pyc) and if it finds it, will attempt to call initfoo() to initialize it.

In your code you create a python module with the name example, so the output file must be example.pyd.

Edit:

The pybind11 FAQ mentions an incompatible python version as another possible error source (https://pybind11.readthedocs.io/en/stable/faq.html):

ImportError: dynamic module does not define init function

  1. Make sure that the name specified in pybind::module and PYBIND11_PLUGIN is consistent and identical to the filename of the extension library. The latter should not contain any extra prefixes (e.g. test.so instead of libtest.so).

  2. If the above did not fix your issue, then you are likely using an incompatible version of Python (for instance, the extension library was compiled against Python 2, while the interpreter is running on top of some version of Python 3, or vice versa)

Community
  • 1
  • 1
pschill
  • 5,055
  • 1
  • 21
  • 42