TDM-GCC编译的win32x64 DLL不能在python 3.6中加载,但在使用python 2.7时可以加载 cmd.exe的我的环境控制台输出
如下控制台输出所示,我使用两个版本的python。我使用Code::Blocks 16.01创建了一个DLL项目,它使用GNU GCC编译器的TDM-GCC(codeblocks中包含的GNU GCC编译器无法构建x86_64程序,它构建的x86 DLL在使用以下代码加载时导致WindowsError:[Error 193]) python代码(testdll.py) DLL C++代码(主要由代码块生成) 问题 使用TDM-GCC编译的win32x64 DLL不能在python 3.6中加载,但在使用python 2.7时可以加载 cmd.exe的我的环境控制台输出,python,winapi,dll,ctypes,tdm-gcc,Python,Winapi,Dll,Ctypes,Tdm Gcc,如下控制台输出所示,我使用两个版本的python。我使用Code::Blocks 16.01创建了一个DLL项目,它使用GNU GCC编译器的TDM-GCC(codeblocks中包含的GNU GCC编译器无法构建x86_64程序,它构建的x86 DLL在使用以下代码加载时导致WindowsError:[Error 193]) python代码(testdll.py) DLL C++代码(主要由代码块生成) 问题 使用py-2testdll.py时,它工作正常,并获得消息框和控制台日志“dll已
py-2testdll.py
时,它工作正常,并获得消息框和控制台日志“dll已加载”,但当
使用python-3testdll.py,这里是回溯
Y:\testdll\bin\Release>py -3 testdll.py
Traceback (most recent call last):
File "testdll.py", line 10, in <module>
lib = ctypes.WinDLL(DLL_PATH)
File "E:\Python36x64\lib\ctypes\__init__.py", line 348, in __init__
self._handle = _dlopen(self._name, mode)
OSError: [WinError 1114]
谁能告诉我为什么,谢谢你,我真的很困惑
我刚刚重新运行了这些步骤(使用命令行而不是代码块)1、复制上面发布的代码(并保存在某处)
2、打开cmd.exe
3、运行以下命令(并将输出粘贴到此处)
4,重新运行py-3 testdll.py 我仍然得到了OSError:[WinError 1114] 但这一次,我删除了上面提到的函数,Python3.6仍然拒绝加载该dll:( 5、检查
py-3
和py-2
和gcc--version
,确认版本保持不变
我的解决方案
将代码块生成的项目编译到Windell失败;我尝试使用下面的命令将手动编写的源代码编译到cdll以获得本机速度(但无法使用一些宏,例如DLL\u EXPORT
)
$(GCC) $< -o $@ -I $(SRC_DIR)/common/crapto1/ -Wl,crapto1.dll -shared
g++ test.cpp -o test.dll -shared
etc.
$(GCC)$<-o$@-I$(SRC_DIR)/common/crapto1/-Wl,crapto1.dll-共享
g++test.cpp-o test.dll-共享
等
下面的代码由我的g++和py2、py3成功编译和加载
#include <cstdio>
#include <windows.h>
using namespace std;
extern "C" int foo();
int foo(){
printf("This Works!\n");
MessageBoxA(0, "This Works!", "DLL Message", MB_OK | MB_ICONINFORMATION);
return 0;
}
//ctypes.WinDLL(DLL_PATH).foo()
//ctypes.cdll.LoadLibrary(DLL_PATH).foo() #both works fine in Python 2 and Python 3
#包括
#包括
使用名称空间std;
外部“C”int foo();
int foo(){
printf(“这有效!\n”);
MessageBoxA(0,“这很有效!”,“DLL消息”,MB|U OK|MB|U图标信息);
返回0;
}
//ctypes.windell(DLL_PATH).foo()
//ctypes.cdll.LoadLibrary(DLL_PATH).foo()#在Python2和Python3中都可以正常工作
你查过错误代码的含义吗?从链接中获得错误1114,它说“动态链接库(DLL)初始化例程失败。”在谷歌搜索到错误代码后,有人说本机dll可能有错误,需要重建。但在我的情况下,同一个dll在Python 2上运行良好,这让我感到困惑。你能告诉我代码或构建选项是否有问题吗?经过几次更改后,谢谢你的时间(主要是#define
s并将extern“C”
添加到SomeFunction
-我不知道它是如何为您工作的),并且使用MinGW64的g++,它可以与两个Python版本一起工作。我添加了缺少的main.h(它包括一些#define,它完全是由代码块自动生成的,所以我认为它并不重要,一开始就忘了发布它),使用MinGW64 g++有效?我会尝试一下,谢谢你,但我仍然担心TDM-GCC为什么不起作用,一定有原因,要么是我犯了错误,要么是我的环境配置错误,另一个原因是我主要是为了另一个目的使用MinGW(工具链是为另一个平台配置的)。不可能。这不起作用(也不应该起作用)。您使用的代码与您发布的代码不同。请编辑问题并添加正确的信息。
#ifndef __MAIN_H__
#define __MAIN_H__
#include <windows.h>
/* To use this exported function of dll, include this header
* in your project.
*/
#ifdef BUILD_DLL
#define DLL_EXPORT __declspec(dllexport)
#else
#define DLL_EXPORT __declspec(dllimport)
#endif
#ifdef __cplusplus
extern "C"
{
#endif
void DLL_EXPORT SomeFunction(const LPCSTR sometext);
#ifdef __cplusplus
}
#endif
#endif // __MAIN_H__
-------------- Build: Release in testdll (compiler: TDM-GCC of GNU GCC Compiler)---------------
[ 50.0%] g++.exe -m64 -Wall -DBUILD_DLL -O2 -Wshadow -Winit-self -Winline -Wswitch-default -Wmain -Wfatal-errors -std=c++11 -g -Weffc++ -Wextra -Wall -Wno-comment -DLOCAL -IE:\TDM-GCC-64\include -c Y:\testdll\main.cpp -o obj\Release\main.o
[100.0%] g++.exe -shared -Wl,--output-def=bin\Release\libtestdll.def -Wl,--out-implib=bin\Release\libtestdll.a -Wl,--dll -LE:\TDM-GCC-64\lib obj\Release\main.o -o bin\Release\testdll.dll -m64 -s -luser32
Y:\testdll\bin\Release>py -3 testdll.py
Traceback (most recent call last):
File "testdll.py", line 10, in <module>
lib = ctypes.WinDLL(DLL_PATH)
File "E:\Python36x64\lib\ctypes\__init__.py", line 348, in __init__
self._handle = _dlopen(self._name, mode)
OSError: [WinError 1114]
char* bar(char* a, char* b)//the only function i added, which was copied from someone
{
char* out = new char[strlen(a) + strlen(b) + 1];// after some test, I think
// this line caused this problem
// using such as
//volatile char *ppp=new char[66];
// will cause the dll file become 100kB+ larger and can't be loaded by Python 3.6
// ##(some strange thing happens, when I rerun this, this function no longer matters, it can't be loaded by Python3.6 anyways)##
strcpy(out, a);
strcat(out, b);
return out;
}
Y:\tmp>g++.exe -m64 -Wall -DBUILD_DLL -O2 -Wshadow -Winit-self -Winline -Wswitch-default -Wmain -Wfatal-errors -std=c++11 -g -Weffc++ -Wextra -Wall -Wno-comment -DLOCAL -IE:\TDM-GCC-64\include -c main.cpp -o main.o
main.cpp: In function 'BOOL DllMain(HINSTANCE, DWORD, LPVOID)':
main.cpp:15:20: warning: unused variable 'aaa' [-Wunused-variable]
volatile char* aaa = new char[100];
^
main.cpp: At global scope:
main.cpp:12:55: warning: unused parameter 'hinstDLL' [-Wunused-parameter]
extern "C" DLL_EXPORT BOOL APIENTRY DllMain(HINSTANCE hinstDLL, DWORD fdwReason, LPVOID lpvReserved)
^
main.cpp:12:89: warning: unused parameter 'lpvReserved' [-Wunused-parameter]
extern "C" DLL_EXPORT BOOL APIENTRY DllMain(HINSTANCE hinstDLL, DWORD fdwReason, LPVOID lpvReserved)
^
Y:\tmp>g++.exe -shared -Wl,--output-def=libtestdll.def -Wl,--out-implib=libtestdll.a -Wl,--dll -LE:\TDM-GCC-64\lib main.o -o testdll.dll -m64 -s -luser32
$(GCC) $< -o $@ -I $(SRC_DIR)/common/crapto1/ -Wl,crapto1.dll -shared
g++ test.cpp -o test.dll -shared
etc.
#include <cstdio>
#include <windows.h>
using namespace std;
extern "C" int foo();
int foo(){
printf("This Works!\n");
MessageBoxA(0, "This Works!", "DLL Message", MB_OK | MB_ICONINFORMATION);
return 0;
}
//ctypes.WinDLL(DLL_PATH).foo()
//ctypes.cdll.LoadLibrary(DLL_PATH).foo() #both works fine in Python 2 and Python 3