1

Okay so according to the answer I found here to the question titled "Calling C/C++ from Python?" here, and also on the cppyy documentation website, I made some sample classes in .h and .cpp files and tried to include them in Python. While the .h file gets included easily, when I try to use the cppyy.load_library() function, it gives me a runtime error for some reason. Can someone please help? I've tried to look for solutions online but apparently no one has got a similar problem before. This is what I'm running in Jupyter Notebook:

import cppyy
cppyy.include("foo.h")
cppyy.load_library("libfoo")

the final line is giving me the following error:

RuntimeError                              Traceback (most recent call last)
<ipython-input-3-eea6173ad08e> in <module>
----> 1 cppyy.load_library("libfoo")

~\anaconda3\lib\site-packages\cppyy\__init__.py in load_library(name)
    219         sc = gSystem.Load(name)
    220     if sc == -1:
--> 221         raise RuntimeError('Unable to load library "%s"%s' % (name, err.err))
    222     return True
    223 

RuntimeError: Unable to load library "libfoo"

This is my .h file:

class Foo {
    public:
        void bar();
};

And here is my .cpp file:

#include "foo.h"
#include <iostream>

void Foo::bar() { std::cout << "Hello" << std::endl; }

I'm using the commands g++ -c -fPIC foo.cpp -o foo.o and g++ -shared -Wl,-soname,libfoo.so -o libfoo.so foo.o to compile my cpp code.

Please can someone help?

  • First thing I'd do is make sure the library is where Python is looking for it. `"libfoo"` loos to me like it's going to search the [working directory](https://en.wikipedia.org/wiki/Working_directory) and then the [system path](https://en.wikipedia.org/wiki/PATH_(variable)). I also suspect, but don't know for sure, that `cppyy.load_library("libfoo")` should be `cppyy.load_library("libfoo.so")` – user4581301 Aug 06 '21 at 21:13
  • no the extension is added automatically. But even after changing the system path, it still doesn't work. Neither does using the ```add_library_path``` function nor does using ```os``` module to change my working directory in python prompt. I'm entirely clueless here – KuuhakuBlank00 Aug 07 '21 at 04:20

1 Answers1

0

The example works just fine for me.

To debug, first make sure to start python in the same directory where libfoo.so is located, or to add the directory where libfoo.so lives to LD_LIBRARY_PATH (for any process to use), or call cppyy.add_library_path() with the path as argument to add it for use by cppyy only. As concerns the name, the .so extension is automatically added as needed, as is the lib part, so either one of foo, libfoo, foo.so, or libfoo.so is fine.

If that still fails, a reasonable way on Linux (only) of getting more information for what could be going wrong, is to use ctypes:

$ python
>>> import cypes
>>> lib = ctypes.CDLL("libfoo.so")

which will show you if there are different problems such as missing symbols or missing dependent libraries (but neither is the case here).

Wim Lavrijsen
  • 3,453
  • 1
  • 9
  • 21
  • Okay so the thing is, I'm on a Windows system, So I added my directory to the environment PATH variable. when I try to load the library using ctypes in Jupyter Notebook, it works without any errors. However, it doesn't work with ```cppyy.load_library()``` for whatever reason. I've also tried to do this in command prompt by importing the ```os``` module and then using it to change the working directory, but it didn't work. I also tried the ```add_library_path``` function before changing the PATH variable but that still didn't work. My path is: "C:\Users\athar\Documents\Programming\C++ programs" – KuuhakuBlank00 Aug 07 '21 at 04:18
  • I also opened a new anaconda prompt, changed my working directory to the one mentioned above, opened python there. Still doesn't work. – KuuhakuBlank00 Aug 07 '21 at 04:28
  • I assumed Linux b/c you used g++ in the command above. I've never tried g++ on Windows, only MSVC. Note that for Windows, `load_library` will look for the `.dll` extension, not `.so`, so you'll have to be explicit and have use the full name of `libfoo.so`. If `ctypes.CDLL` works, then you can also use `ctypes.CDLL('libfoo.so', ctypes.RTLD_GLOBAL)` instead of `cppyy.load_library()`. – Wim Lavrijsen Aug 07 '21 at 15:15
  • I tried that, but it's not working still. Also, if I use the ```cppyy.cppdef()``` function to write the code and then run it, will that still give me C++'s high computation speed? Because honestly I could just write code in an editor, test it and then add paste it into the ```cppdef()``` function. – KuuhakuBlank00 Aug 07 '21 at 16:54
  • Yes, `cppdef` generates optimized code, just that it will compile each and every time that it is executed, so if the code is large, loading a library is way faster. – Wim Lavrijsen Aug 08 '21 at 04:23
  • Oh okay I guess I can work with that. Just for clarification, let's say I'm using Jupyter Notebook and in one cell I've used ```cppdef``` to define my class and all the functions in it. And in some other cell below it, I'm calling one of those functions. Will it then have to compile the cpp code every time I call a function? Or it will only be compiled once after I've run the cell containing ```cppdef``` and then I'm free to call the functions as many times as I want without having to wait for compilation at each function call? – KuuhakuBlank00 Aug 08 '21 at 07:30
  • Yes, it's compiled once and the compiled code will stay around for the lifetime of the kernel. This also means that it's not really possible to redefine code (that is, there are severe limitations; this is something that will improve only with OrcJIT v2, which completely reimplements the JIT linker). Easiest way to work around that is to namespace different versions of the code. – Wim Lavrijsen Aug 08 '21 at 18:15