2

I follow instructions of this page to try to call C++ functions.
Calling C/C++ from Python?

I write a pylib.cpp

#include <iostream>

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

extern "C" {
    Foo* Foo_new() { return new Foo(); }
    void Foo_bar(Foo* foo) { foo->bar(); }
}

and then use these commands on Win 10 terminal:

g++ -c -fPIC pylib.cpp -o pylib.o
g++ -shared -Wl,-soname,pylib.so -o pylib.so  pylib.o

I get the message in the terminal. Just a warning. The pylib.so still be maked by g++.

pylib.cpp:1:0: warning: -fPIC ignored for target (all code is position independent)
 #include <iostream>
 ^

I write a pylib.py:

from ctypes import *

lib = cdll.LoadLibrary('pylib.so')
f = lib.Foo()
f.bar()

I got the error message:

Traceback (most recent call last):
  File "C:/Users/Jack/PycharmProjects/dip_hw1/pylib.py", line 3, in <module>
    lib = cdll.LoadLibrary('pylib.so')
  File "C:\Python\lib\ctypes\__init__.py", line 426, in LoadLibrary
    return self._dlltype(name)
  File "C:\Python\lib\ctypes\__init__.py", line 348, in __init__
    self._handle = _dlopen(self._name, mode)
OSError: [WinError 1114] 動態連結程式庫 (DLL) 初始化例行程序失敗。

OSError: [WinError 1114] 動態連結程式庫 (DLL) 初始化例行程序失敗。
this meaning likes
OSError: [WinError 1114] Dynamic-link library (DLL) initialization routine failed

My environment is

Python: Python 3.6.6 (v3.6.6:4cf1f54eb7, Jun 27 2018, 03:37:03) [MSC v.1900 64 bit (AMD64)] on win32
C/C++ Compiler: TDM-GCC MinGW
OS: Win 10

I can load C library well. but I continue get dll error after trying a lot of various methods to write the C++ code, or to make share library with different way.


Note that: the name of cpp library changes to pylib2.dll. whatever I use .so for .dll for dll file name, I get the same error.

This is the command example

C:\Users\Jack\PycharmProjects\dip_hw1>dir
 磁碟區 C 中的磁碟沒有標籤。
 磁碟區序號:  1AB4-8568

 C:\Users\Jack\PycharmProjects\dip_hw1 的目錄

2018/09/20  下午 03:26    <DIR>          .
2018/09/20  下午 03:26    <DIR>          ..
2018/09/20  下午 10:49    <DIR>          .idea
2018/09/18  上午 11:12    <DIR>          image
2015/06/28  下午 02:28            58,880 libatomic-1.dll
2015/06/28  下午 02:28            69,120 libatomic_64-1.dll
2013/09/01  上午 09:38           149,207 libcharset-1.dll
2015/06/28  上午 05:50           145,934 libgcc_s_dw2-1.dll
2015/06/28  下午 02:28           114,176 libgcc_s_seh_64-1.dll
2015/06/28  下午 02:28           120,832 libgcc_s_sjlj-1.dll
2015/06/28  下午 02:28           934,400 libiconv-2.dll
2014/04/27  上午 06:46           484,613 libintl-8.dll
2015/06/28  下午 02:28           359,936 libquadmath-0.dll
2015/06/28  下午 02:28           354,816 libquadmath_64-0.dll
2015/06/28  下午 02:28            13,824 libssp-0.dll
2015/06/28  下午 02:28            18,944 libssp_64-0.dll
2015/06/28  下午 02:28         1,374,208 libstdc++-6.dll
2015/06/28  下午 02:28         1,405,952 libstdc++_64-6.dll
2015/06/28  下午 02:28            11,264 libvtv-0.dll
2015/06/28  下午 02:28            15,872 libvtv_64-0.dll
2015/06/28  下午 02:28            11,264 libvtv_stubs-0.dll
2015/06/28  下午 02:28            15,872 libvtv_stubs_64-0.dll
2015/06/28  下午 02:28            60,928 libwinpthread-1.dll
2015/06/28  下午 02:28            64,512 libwinpthread_64-1.dll
2018/09/17  下午 04:55             1,918 main.cpython-36.pyc
2018/09/19  下午 12:14            10,587 main.py
2018/09/19  下午 08:11           113,157 pylib.dll
2018/09/20  下午 03:26               188 pylib.py
2018/09/19  下午 11:02         2,695,132 pylib2.dll
2018/09/19  下午 11:07         2,695,135 pylib2.so
2018/09/17  下午 04:56                26 run.bat
2018/09/19  下午 02:05               627 test.py
2018/09/17  下午 04:55    <DIR>          __pycache__
              28 個檔案      11,301,324 位元組
               5 個目錄  171,916,886,016 位元組可用

C:\Users\Jack\PycharmProjects\dip_hw1>python pylib.py
C:\Users\Jack\PycharmProjects\dip_hw1
C:\Users\Jack\PycharmProjects\dip_hw1
Traceback (most recent call last):
  File "pylib.py", line 7, in <module>
    lib = cdll.LoadLibrary('pylib2.dll')
  File "C:\Python\lib\ctypes\__init__.py", line 426, in LoadLibrary
    return self._dlltype(name)
  File "C:\Python\lib\ctypes\__init__.py", line 348, in __init__
    self._handle = _dlopen(self._name, mode)
OSError: [WinError 1114] 動態連結程式庫 (DLL) 初始化例行程序失敗。

And this is the new pylib.py code

from ctypes import *
import os
dir_path = os.path.dirname(os.path.realpath(__file__))
print(dir_path)
print(os.getcwd())

lib = cdll.LoadLibrary('pylib2.dll')
f = lib.Foo()
f.bar()
4
  • 1
    Is this a windows DLL or as Posix shared object you have created? Do you have all the DLLs that pylib.so references available (on the path basically) - check with depends.exe (if you don't know what that is, search for it and download it now - it's a vital tool in a Windows developer's armoury). Commented Sep 19, 2018 at 13:46
  • What platform are you on? For Window's Id advise Microsoft Visual Studio Community (free), or at least some tool rather than manual command lines, and you certainly want a DLL, not an so. Commented Sep 19, 2018 at 13:48
  • If pylib.so is a C share library which is build by gcc command, then cdll.LoadLibrary('pylib.so') work. So it's seem to not require .dll. Commented Sep 19, 2018 at 13:55
  • I survey a lot of ctypes usages, they all use command line. Not using any certain IDE like Visual Studio. Commented Sep 19, 2018 at 13:58

2 Answers 2

2

I find the solution by myself. The solution is:

  1. Using MinGW comipler or Microsoft C/C++ compiler.
  2. Using Python 32 bit interpreter.
  3. It is not necessary to copy dll from compiler bin folder.

First, I used the TDM-GCC MinGW Compiler as C/C++ compiler before. Then I try another compiler: MinGW. I can't tell you what different between them, I'm not a pro guy. But they produce different error message when I use ctypes to load the two different dll library which compile by both in the Python 3.6.6 64 bit interpreter. They all failed on Python 3.6.6 64 bit interpreter.

I try 32-bit python to load dll library. It successes to load library.
The pylib.cpp code:

#include <iostream>
using namespace std;

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

extern "C" {
    Foo* Foo_new() { return new Foo(); }
    void Foo_bar(Foo* foo) { foo->bar(); }
}

Compile command:

g++ -shared -o pylib.dll pylib.cpp

The pylib.py code:

from ctypes import *

lib = cdll.LoadLibrary('pylib.dll')
f = lib.Foo_new()
lib.Foo_bar(f)

The ouput:

Hello

Thanks for pschill and others propose new methods.

Sign up to request clarification or add additional context in comments.

1 Comment

I had to use lib = cdll.LoadLibrary('./pylib.dll') to convince ctypes I wasn't looking for a system library.
0

You are using gcc from MinGW to compile and link the code. Since the code uses the C++ standard library (#include <iostream> resp. std::cout), you need to make the libstdc++-6.dll file available which ships with gcc. Copy the .dll into the working directory, then it should work.

11 Comments

I use g++ to compile.
Yes, using g++ is correct. gcc stands for GNU Compiler Collection and the C++ compiler of gcc is g++.
I will get error when I use gcc to compile the .cpp code.
Oh! So I need to find and copy libstdc++-6.dll into the directory that the .so file locate? I think it is the working directory you talk about.
I copy all the .dll in the TDM-GCC-64\bin to the working directory. But I get the same dll error again...
|

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.