Скомпилированная TDM-GCC win32x64 DLL не может быть загружена в python 3.6, но может при использовании python 2.7
мой вывод консоли среды cmd.exe
Microsoft Windows [10.0.15063.1112]
(c) 2017 Microsoft Corporation
C:\Users\>py -3
Python 3.6.4 (v3.6.4:d48eceb, Dec 19 2017, 06:54:40) [MSC v.1900 64 bit (AMD64)] on win32
Type "help", "copyright", "credits" or "license" for more information.
>>>
C:\Users\>py -2
Python 2.7.13 (v2.7.13:a06454b1afa1, Dec 17 2016, 20:53:40) [MSC v.1500 64 bit (AMD64)] on win32
Type "help", "copyright", "credits" or "license" for more information.
>>>
E:\TDM-GCC-64\bin>gcc --version
gcc (tdm64-1) 5.1.0
Copyright (C) 2015 Free Software Foundation, Inc.
как показано в выводе консоли, я использую две версии python. И я создал проект DLL, используя Code::Blocks 16.01, который использует TDM-GCC компилятора GNU GCC (компилятор GNU GCC, включенный в кодовые блоки, не может собрать программу x86_64, а созданный ею x86 вызвал ошибку WindowsError:[Ошибка 193] при загрузке с использованием следующего кода)
код Python здесь (testdll.py)
import ctypes
DLL_PATH = './testdll.dll'
lib = ctypes.WinDLL(DLL_PATH)
# or #lib = ctypes.cdll.LoadLibrary(DLL_PATH)
#didn't work in python3.6
print("dll loaded")
lib.SomeFunction(b"12345")
код dll C++ (в основном генерируется кодовыми блоками)
#include "main.h"
#include <cstring>
using namespace std;
// a sample exported function
void DLL_EXPORT SomeFunction(const LPCSTR sometext)
{
MessageBoxA(0, sometext, "DLL Message", MB_OK | MB_ICONINFORMATION);
}
extern "C" DLL_EXPORT BOOL APIENTRY DllMain(HINSTANCE hinstDLL, DWORD fdwReason, LPVOID lpvReserved)
{
volatile char* aaa = new char[100];
switch (fdwReason)
{
case DLL_PROCESS_ATTACH:
// attach to process
// return FALSE to fail DLL load
break;
case DLL_PROCESS_DETACH:
// detach from process
break;
case DLL_THREAD_ATTACH:
// attach to thread
break;
case DLL_THREAD_DETACH:
// detach from thread
break;
default:
break;
}
return TRUE; // succesful
}
char* bar(char* a, char* b)//the only function i added, which was copied from someone's blog
{
char* out = new char[strlen(a) + strlen(b) + 1];
strcpy(out, a);
strcat(out, b);
return out;
}
вот главный.ч
#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__
Параметры компиляции DLL (журнал сборки)
-------------- 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
проблема
когда используешь py -2 testdll.py
, он работает нормально и получил окно сообщения и журнал консоли 'dll загружен', но при использовании python -3 testdll.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]
и когда я удалил эту функцию (код ниже) из кода C++, нажмите кнопку перестроения, перезапустите код Python, используя Python2 или Python3, оба прекрасно работают и получают правильный вывод.
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
strcpy(out, a);
strcat(out, b);
return out;
}
кто может сказать мне, почему, спасибо, я действительно запутался.