No se puede usar ctypes pitón para cargar recurso compartido de biblioteca C ++

votos
0

Sigo las instrucciones de esta página para intentar llamar funciones de C ++.
Llamando C / C ++ desde Python?

Escribo un 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(); }
}

y luego utilizar estos comandos en Win 10 de terminal:

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

Consigo el mensaje en el terminal. Sólo una advertencia. El pylib.so todavía ser maked por g ++.

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

Escribo un pylib.py :

from ctypes import *

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

Tengo el mensaje de error:

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)初始化例行程序失敗.
Este sentido le gusta
OSError: [winError 1114] biblioteca de vínculos dinámicos (DLL) rutina de inicialización falló

Mi entorno es

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

Puedo cargar así biblioteca C. pero sigo obtener error de dll después de probar una gran cantidad de diferentes métodos para escribir el código C ++, o para hacer recurso compartido de biblioteca con forma diferente.


Tenga en cuenta que: el nombre de la biblioteca CPP cambios a pylib2.dll. lo utilizo .sopara .dllel nombre del archivo DLL, me sale el mismo error.

Este es el ejemplo de comando

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) 初始化例行程序失敗。

Y este es el nuevo pylib.py código

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()
Publicado el 19/09/2018 a las 13:24
fuente por usuario
En otros idiomas...                            


2 respuestas

votos
0

Me parece la solución por mí mismo. La solucion es:

  1. Utilizando MinGW comipler o compilador de Microsoft C / C ++.
  2. Al utilizar Python intérprete de 32 bits.
  3. No es necesario copiar DLL de la carpeta bin del compilador.

En primer lugar, he usado el compilador MinGW TDM-CCG como C / C ++ antes. Entonces intento otra compilador: MinGW . No puedo decir lo diferente entre ellos, yo no soy un tipo profesional. Sino que producen diferentes mensajes de error cuando se utiliza ctypespara cargar los dos biblioteca DLL diferente, que compila por tanto en el Python 3.6.6 64 bitintérprete. Todos ellos fracasaron en Python 3.6.6 64 bitintérprete.

Trato pitón de 32 bits para cargar la biblioteca DLL. It éxitos cargar la biblioteca.
El pylib.cpp código:

#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(); }
}

Compilar comando:

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

El pylib.py código:

from ctypes import *

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

Que la salida:

Hello

Gracias por Pschill y otros proponen nuevos métodos.

Respondida el 22/09/2018 a las 06:50
fuente por usuario

votos
0

Se está empleando gcc de MinGW para compilar y enlazar el código. Dado que el código utiliza la biblioteca de C ++ estándar ( #include <iostream>resp. std::cout), Es necesario hacer que el libstdc++-6.dllarchivo disponible que se suministra con gcc. Copiar el archivo .dll en el directorio de trabajo, entonces debería funcionar.

Respondida el 19/09/2018 a las 14:22
fuente por usuario

Cookies help us deliver our services. By using our services, you agree to our use of cookies. Learn more