为什么在Python上正确导入我的C dll而不是我的C++;动态链接库?
操作系统:Windows 10 64位 Python:3.9.5 64位 编译器:gcc版本8.1.0(x86_64-posix-seh-rev0,由MinGW-W64项目构建) 问题:我对Python不太了解,我尝试导入一些非常基本的DLL来开始。我不明白为什么在我的计算机上找到了一个C DLL,而找不到C++ DLL。 C代码(mini.C):为什么在Python上正确导入我的C dll而不是我的C++;动态链接库?,python,c++,dll,Python,C++,Dll,操作系统:Windows 10 64位 Python:3.9.5 64位 编译器:gcc版本8.1.0(x86_64-posix-seh-rev0,由MinGW-W64项目构建) 问题:我对Python不太了解,我尝试导入一些非常基本的DLL来开始。我不明白为什么在我的计算机上找到了一个C DLL,而找不到C++ DLL。 C代码(mini.C): #include <stdio.h> extern "C" { __declspec( dlle
#include <stdio.h>
extern "C" {
__declspec( dllexport ) void hi() {
printf("\nHello World from C !\n");
}
}
#include <iostream>
extern "C" {
__declspec(dllexport) void hi() {
std::cout << std::endl << "Hello World from C++ !" << std::endl;
}
}
all: mini.dll mini_cpp.dll
mini.dll: mini.o
g++ mini.o -shared -Wl,--out-implib,libmini.a -o mini.dll
mini.o: mini.c
g++ -c mini.c -I . -o mini.o
mini_cpp.dll: mini_cpp.o
g++ mini_cpp.o -shared -Wl,--out-implib,libmini_cpp.a -o mini_cpp.dll
mini_cpp.o: mini_cpp.cpp
g++ -c mini_cpp.cpp -I . -o mini_cpp.o
g++ -c mini.c -I . -o mini.o
g++ mini.o -shared -Wl,--out-implib,libmini.a -o mini.dll
g++ -c mini_cpp.cpp -I . -o mini_cpp.o
g++ mini_cpp.o -shared -Wl,--out-implib,libmini_cpp.a -o mini_cpp.dll
Python 3.9.5 (tags/v3.9.5:0a7dcbd, May 3 2021, 17:27:52) [MSC v.1928 64 bit (AMD64)] on win32
Type "help", "copyright", "credits" or "license" for more information.
>>> import os
>>>
>>> import ctypes
>>>
>>> from ctypes import *
>>>
>>> my_lib = windll.LoadLibrary( os.path.abspath( "mini.dll") )
>>>
>>> my_func = my_lib.hi
>>>
>>> my_func.restype = c_char_p
>>>
>>> my_func()
Hello World from C !
>>> my_cpp_lib = windll.LoadLibrary( os.path.abspath( "mini_cpp.dll") )
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
File "C:\Users\AGENT_TI\AppData\Local\Programs\Python\Python39\lib\ctypes\__init__.py", line 452, in LoadLibrary
return self._dlltype(name)
File "C:\Users\AGENT_TI\AppData\Local\Programs\Python\Python39\lib\ctypes\__init__.py", line 374, in __init__
self._handle = _dlopen(self._name, mode)
FileNotFoundError: Could not find module 'C:\Users\AGENT_TI\Desktop\STRINGS\python\mini_cpp.dll' (or one of its dependencies). Try using the full path with constructor syntax.
>>>
>>> import os
>>>
>>> import ctypes
>>>
>>> from ctypes import *
>>>
>>> my_lib = windll.LoadLibrary( os.path.abspath( "mini.dll") )
>>>
>>> my_func = my_lib.hi
>>>
>>> my_func.restype = c_char_p
>>>
>>> my_func()
Hello World from C !
>>>
>>> windll.LoadLibrary("C:\\mingw-w64\\x86_64-8.1.0-posix-seh-rt_v6-rev0\\mingw64\\x86_64-w64-mingw32\\lib\\libstdc++-6.dll")
<WinDLL 'C:\mingw-w64\x86_64-8.1.0-posix-seh-rt_v6-rev0\mingw64\x86_64-w64-mingw32\lib\libstdc++-6.dll', handle 6fc40000 at 0x25a1f2ade50>
>>>
>>> my_cpp_lib = windll.LoadLibrary( os.path.abspath( "mini_cpp.dll") )
>>>
>>> my_cpp_func = my_cpp_lib.hi
>>>
>>> my_cpp_func.restype = c_wchar_p
>>>
>>> my_cpp_func()
Hello World from C++ !
'\uf038濑'
>>>
C DLL的Python代码和结果:
#include <stdio.h>
extern "C" {
__declspec( dllexport ) void hi() {
printf("\nHello World from C !\n");
}
}
#include <iostream>
extern "C" {
__declspec(dllexport) void hi() {
std::cout << std::endl << "Hello World from C++ !" << std::endl;
}
}
all: mini.dll mini_cpp.dll
mini.dll: mini.o
g++ mini.o -shared -Wl,--out-implib,libmini.a -o mini.dll
mini.o: mini.c
g++ -c mini.c -I . -o mini.o
mini_cpp.dll: mini_cpp.o
g++ mini_cpp.o -shared -Wl,--out-implib,libmini_cpp.a -o mini_cpp.dll
mini_cpp.o: mini_cpp.cpp
g++ -c mini_cpp.cpp -I . -o mini_cpp.o
g++ -c mini.c -I . -o mini.o
g++ mini.o -shared -Wl,--out-implib,libmini.a -o mini.dll
g++ -c mini_cpp.cpp -I . -o mini_cpp.o
g++ mini_cpp.o -shared -Wl,--out-implib,libmini_cpp.a -o mini_cpp.dll
Python 3.9.5 (tags/v3.9.5:0a7dcbd, May 3 2021, 17:27:52) [MSC v.1928 64 bit (AMD64)] on win32
Type "help", "copyright", "credits" or "license" for more information.
>>> import os
>>>
>>> import ctypes
>>>
>>> from ctypes import *
>>>
>>> my_lib = windll.LoadLibrary( os.path.abspath( "mini.dll") )
>>>
>>> my_func = my_lib.hi
>>>
>>> my_func.restype = c_char_p
>>>
>>> my_func()
Hello World from C !
>>> my_cpp_lib = windll.LoadLibrary( os.path.abspath( "mini_cpp.dll") )
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
File "C:\Users\AGENT_TI\AppData\Local\Programs\Python\Python39\lib\ctypes\__init__.py", line 452, in LoadLibrary
return self._dlltype(name)
File "C:\Users\AGENT_TI\AppData\Local\Programs\Python\Python39\lib\ctypes\__init__.py", line 374, in __init__
self._handle = _dlopen(self._name, mode)
FileNotFoundError: Could not find module 'C:\Users\AGENT_TI\Desktop\STRINGS\python\mini_cpp.dll' (or one of its dependencies). Try using the full path with constructor syntax.
>>>
>>> import os
>>>
>>> import ctypes
>>>
>>> from ctypes import *
>>>
>>> my_lib = windll.LoadLibrary( os.path.abspath( "mini.dll") )
>>>
>>> my_func = my_lib.hi
>>>
>>> my_func.restype = c_char_p
>>>
>>> my_func()
Hello World from C !
>>>
>>> windll.LoadLibrary("C:\\mingw-w64\\x86_64-8.1.0-posix-seh-rt_v6-rev0\\mingw64\\x86_64-w64-mingw32\\lib\\libstdc++-6.dll")
<WinDLL 'C:\mingw-w64\x86_64-8.1.0-posix-seh-rt_v6-rev0\mingw64\x86_64-w64-mingw32\lib\libstdc++-6.dll', handle 6fc40000 at 0x25a1f2ade50>
>>>
>>> my_cpp_lib = windll.LoadLibrary( os.path.abspath( "mini_cpp.dll") )
>>>
>>> my_cpp_func = my_cpp_lib.hi
>>>
>>> my_cpp_func.restype = c_wchar_p
>>>
>>> my_cpp_func()
Hello World from C++ !
'\uf038濑'
>>>
#include <stdio.h>
extern "C" {
__declspec( dllexport ) void hi() {
printf("\nHello World from C !\n");
}
}
#include <iostream>
extern "C" {
__declspec(dllexport) void hi() {
std::cout << std::endl << "Hello World from C++ !" << std::endl;
}
}
all: mini.dll mini_cpp.dll
mini.dll: mini.o
g++ mini.o -shared -Wl,--out-implib,libmini.a -o mini.dll
mini.o: mini.c
g++ -c mini.c -I . -o mini.o
mini_cpp.dll: mini_cpp.o
g++ mini_cpp.o -shared -Wl,--out-implib,libmini_cpp.a -o mini_cpp.dll
mini_cpp.o: mini_cpp.cpp
g++ -c mini_cpp.cpp -I . -o mini_cpp.o
g++ -c mini.c -I . -o mini.o
g++ mini.o -shared -Wl,--out-implib,libmini.a -o mini.dll
g++ -c mini_cpp.cpp -I . -o mini_cpp.o
g++ mini_cpp.o -shared -Wl,--out-implib,libmini_cpp.a -o mini_cpp.dll
Python 3.9.5 (tags/v3.9.5:0a7dcbd, May 3 2021, 17:27:52) [MSC v.1928 64 bit (AMD64)] on win32
Type "help", "copyright", "credits" or "license" for more information.
>>> import os
>>>
>>> import ctypes
>>>
>>> from ctypes import *
>>>
>>> my_lib = windll.LoadLibrary( os.path.abspath( "mini.dll") )
>>>
>>> my_func = my_lib.hi
>>>
>>> my_func.restype = c_char_p
>>>
>>> my_func()
Hello World from C !
>>> my_cpp_lib = windll.LoadLibrary( os.path.abspath( "mini_cpp.dll") )
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
File "C:\Users\AGENT_TI\AppData\Local\Programs\Python\Python39\lib\ctypes\__init__.py", line 452, in LoadLibrary
return self._dlltype(name)
File "C:\Users\AGENT_TI\AppData\Local\Programs\Python\Python39\lib\ctypes\__init__.py", line 374, in __init__
self._handle = _dlopen(self._name, mode)
FileNotFoundError: Could not find module 'C:\Users\AGENT_TI\Desktop\STRINGS\python\mini_cpp.dll' (or one of its dependencies). Try using the full path with constructor syntax.
>>>
>>> import os
>>>
>>> import ctypes
>>>
>>> from ctypes import *
>>>
>>> my_lib = windll.LoadLibrary( os.path.abspath( "mini.dll") )
>>>
>>> my_func = my_lib.hi
>>>
>>> my_func.restype = c_char_p
>>>
>>> my_func()
Hello World from C !
>>>
>>> windll.LoadLibrary("C:\\mingw-w64\\x86_64-8.1.0-posix-seh-rt_v6-rev0\\mingw64\\x86_64-w64-mingw32\\lib\\libstdc++-6.dll")
<WinDLL 'C:\mingw-w64\x86_64-8.1.0-posix-seh-rt_v6-rev0\mingw64\x86_64-w64-mingw32\lib\libstdc++-6.dll', handle 6fc40000 at 0x25a1f2ade50>
>>>
>>> my_cpp_lib = windll.LoadLibrary( os.path.abspath( "mini_cpp.dll") )
>>>
>>> my_cpp_func = my_cpp_lib.hi
>>>
>>> my_cpp_func.restype = c_wchar_p
>>>
>>> my_cpp_func()
Hello World from C++ !
'\uf038濑'
>>>
my_cpp_lib=windell.LoadLibrary(os.path.abspath(“mini_cpp.dll”))
回溯(最近一次呼叫最后一次):
文件“”,第1行,在
LoadLibrary中第452行的文件“C:\Users\AGENT\u TI\AppData\Local\Programs\Python\Python39\lib\ctypes\\uuuuuu init\uuuuu.py”
返回自我类型(名称)
文件“C:\Users\AGENT\u TI\AppData\Local\Programs\Python39\lib\ctypes\\uuuuuu init\uuuuu.py”,第374行,在\uuu init中__
self.\u handle=\u dlopen(self.\u名称,模式)
FileNotFoundError:找不到模块“C:\Users\AGENT\TI\Desktop\STRINGS\python\mini\u cpp.dll”(或其依赖项之一)。尝试使用构造函数语法的完整路径。
>>>
~~
我已经尝试过的:
- Python中的不同os.path操作:
- 用GCC编译而不是G++(加上-+LSTDC++ + C++代码)
如果有人已经遇到了这个问题并进行了一些修复,谢谢…Paxdiablo:您对dll问题的假设是正确的(我100%同意消息的准确性不足导致如此浪费时间) objdump向我展示了mini_cpp.dll的以下内容:
DLL Name: libstdc++-6.dll
vma: Hint/Ord Member-Name Bound-To
9588 1739 _ZNSolsEPFRSoS_E
959c 4448 _ZNSt8ios_base4InitC1Ev
95b8 4450 _ZNSt8ios_base4InitD1Ev
95d4 4738 _ZSt4cout
95e0 4739 _ZSt4endlIcSt11char_traitsIcEERSt13basic_ostreamIT_T0_ES6_
9620 4847 _ZStlsISt11char_traitsIcEERSt13basic_ostreamIcT_ES5_PKc
CristiFati:我没有尝试静态构建dll,但我想它确实可以工作
顺便说一下,根据您的直觉(事实上-lstdlibc++最终是我的两个dll之间的唯一区别),我只是在dll之前用Python加载了库
结果是好的(尽管我的字符串下有虚假字符,但我想稍后可以在Python中修复)。它解释了为什么尝试使用boost::python或
pythonapi也导致了同样的问题
修改的Python代码和结果:
#include <stdio.h>
extern "C" {
__declspec( dllexport ) void hi() {
printf("\nHello World from C !\n");
}
}
#include <iostream>
extern "C" {
__declspec(dllexport) void hi() {
std::cout << std::endl << "Hello World from C++ !" << std::endl;
}
}
all: mini.dll mini_cpp.dll
mini.dll: mini.o
g++ mini.o -shared -Wl,--out-implib,libmini.a -o mini.dll
mini.o: mini.c
g++ -c mini.c -I . -o mini.o
mini_cpp.dll: mini_cpp.o
g++ mini_cpp.o -shared -Wl,--out-implib,libmini_cpp.a -o mini_cpp.dll
mini_cpp.o: mini_cpp.cpp
g++ -c mini_cpp.cpp -I . -o mini_cpp.o
g++ -c mini.c -I . -o mini.o
g++ mini.o -shared -Wl,--out-implib,libmini.a -o mini.dll
g++ -c mini_cpp.cpp -I . -o mini_cpp.o
g++ mini_cpp.o -shared -Wl,--out-implib,libmini_cpp.a -o mini_cpp.dll
Python 3.9.5 (tags/v3.9.5:0a7dcbd, May 3 2021, 17:27:52) [MSC v.1928 64 bit (AMD64)] on win32
Type "help", "copyright", "credits" or "license" for more information.
>>> import os
>>>
>>> import ctypes
>>>
>>> from ctypes import *
>>>
>>> my_lib = windll.LoadLibrary( os.path.abspath( "mini.dll") )
>>>
>>> my_func = my_lib.hi
>>>
>>> my_func.restype = c_char_p
>>>
>>> my_func()
Hello World from C !
>>> my_cpp_lib = windll.LoadLibrary( os.path.abspath( "mini_cpp.dll") )
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
File "C:\Users\AGENT_TI\AppData\Local\Programs\Python\Python39\lib\ctypes\__init__.py", line 452, in LoadLibrary
return self._dlltype(name)
File "C:\Users\AGENT_TI\AppData\Local\Programs\Python\Python39\lib\ctypes\__init__.py", line 374, in __init__
self._handle = _dlopen(self._name, mode)
FileNotFoundError: Could not find module 'C:\Users\AGENT_TI\Desktop\STRINGS\python\mini_cpp.dll' (or one of its dependencies). Try using the full path with constructor syntax.
>>>
>>> import os
>>>
>>> import ctypes
>>>
>>> from ctypes import *
>>>
>>> my_lib = windll.LoadLibrary( os.path.abspath( "mini.dll") )
>>>
>>> my_func = my_lib.hi
>>>
>>> my_func.restype = c_char_p
>>>
>>> my_func()
Hello World from C !
>>>
>>> windll.LoadLibrary("C:\\mingw-w64\\x86_64-8.1.0-posix-seh-rt_v6-rev0\\mingw64\\x86_64-w64-mingw32\\lib\\libstdc++-6.dll")
<WinDLL 'C:\mingw-w64\x86_64-8.1.0-posix-seh-rt_v6-rev0\mingw64\x86_64-w64-mingw32\lib\libstdc++-6.dll', handle 6fc40000 at 0x25a1f2ade50>
>>>
>>> my_cpp_lib = windll.LoadLibrary( os.path.abspath( "mini_cpp.dll") )
>>>
>>> my_cpp_func = my_cpp_lib.hi
>>>
>>> my_cpp_func.restype = c_wchar_p
>>>
>>> my_cpp_func()
Hello World from C++ !
'\uf038濑'
>>>
导入操作系统
>>>
>>>导入ctypes
>>>
>>>从ctypes导入*
>>>
>>>my_lib=windell.LoadLibrary(os.path.abspath(“mini.dll”))
>>>
>>>my_func=my_lib.hi
>>>
>>>my_func.restype=c_char\p
>>>
>>>my_func()
你好,来自C的世界!
>>>
>>>LoadLibrary(“C:\\mingw-w64\\x86\U 64-8.1.0-posix-seh-rt\U v6-rev0\\mingw64\\x86\U 64-w64-mingw32\\lib\\libstdc++-6.dll”)
>>>
>>>my_cpp_lib=windell.LoadLibrary(os.path.abspath(“mini_cpp.dll”))
>>>
>>>my_cpp_func=my_cpp_lib.hi
>>>
>>>my_cpp_func.restype=c_wchar\u p
>>>
>>>my_cpp_func()
从C++世界问好!
'\uf038濑'
>>>
感谢您的帮助paxdiablo和CristiFati:-)“或其依赖项之一”-这在这里可能很重要:-)加载程序很难将“罪魁祸首是XYZY.dll”这样的消息推到标准错误中,这让我很恼火。建议您找到依赖项查询工具,并调查找不到哪个特定的库/对象。如果使用-static libstdc++?旁注(没有任何函数含义)构建.dll,则会发生什么情况?不要设置返回void的函数的restype(或者如果您希望显式地将其设置为None)。另外,我认为G++产生了CCDL函数(在这种情况下,应该使用CDLL代替WEDLL),但是这只与32位有关。此外,我不知道为什么RO静态C++ LIB“不可测试”。