C++ 如何在执行LoadLibrary(“*.exe”)时初始化CRT
我试图将numpy数组传递给C,并在那里进行一些计算 我正在将可执行文件构建为exe,并导出Python随后调用的一些函数。该过程正常,但我无法使用标准函数,如C++ 如何在执行LoadLibrary(“*.exe”)时初始化CRT,c++,python,c,winapi,msvcrt,C++,Python,C,Winapi,Msvcrt,我试图将numpy数组传递给C,并在那里进行一些计算 我正在将可执行文件构建为exe,并导出Python随后调用的一些函数。该过程正常,但我无法使用标准函数,如printf()。如果我将二进制文件构建为dll,它就会工作。通过在internet上搜索,我了解到dll加载和exe加载(maincrtstartup?)对运行库进行初始化。是否可以复制它们的功能,以便我可以使用printf() Python代码 import numpy as np import ctypes from numpy.
printf()
。如果我将二进制文件构建为dll,它就会工作。通过在internet上搜索,我了解到dll加载和exe加载(maincrtstartup?)对运行库进行初始化。是否可以复制它们的功能,以便我可以使用printf()
Python代码
import numpy as np
import ctypes
from numpy.ctypeslib import ndpointer
lib = ctypes.cdll.LoadLibrary('pycon.exe')
fun = lib.fun
fun.restype = None
fun.argtypes = [ndpointer(ctypes.c_double),
ctypes.c_size_t]
data = np.ones((5,5)).astype('double')
def wfun(d):
fun(d, d.size)
print data
wfun(data)
print data
C代码
#include <stdio.h>
#include <math.h>
extern "C" __declspec(dllexport)
void fun(double *datav, size_t size) {
//printf("crash");
double * data = (double *) datav;
int i;
for (i = 0; i < size; ++i)
data[i] = 1.7159*tanh(0.66666667*data[i]);
}
extern "C" __declspec(dllexport)
void init() {
//what to put here?
}
int main(int argc, char* argv[])
{
return 0;
}
#包括
#包括
外部“C”\u declspec(dllexport)
虚无乐趣(双倍*数据,大小){
//printf(“崩溃”);
双*数据=(双*)数据V;
int i;
对于(i=0;i
我意识到将exe作为dll处理比我想象的要复杂得多。我最终采用了以下解决方法
蟒蛇
import numpy as np
import ctypes as C
lib = C.cdll.LoadLibrary('pycon.exe')
lib.init( C.windll.kernel32.GetProcAddress( C.windll.msvcrt._handle,'printf'))
d = np.ones((5)).astype('double')
lib.fun(d.ctypes.data_as(C.POINTER(C.c_double)), C.c_size_t(5))
import numpy as np
import ctypes as C
import pefile
def unprotect( address):
crap = C.byref(C.create_string_buffer("\x00"*4))
res = C.windll.kernel32.VirtualProtect(address, 0x1000, 0x40, crap)
lib = C.cdll.LoadLibrary('pycon.exe')
k32 = C.windll.kernel32
pe = pefile.PE('pycon.exe')
for entry in pe.DIRECTORY_ENTRY_IMPORT:
#print entry.dll
#assuming that the exe only has dependency on kernel32
for imp in entry.imports:
diff = imp.address-0x400000
memptr = k32.GetProcAddress(k32._handle,imp.name)
unprotect(lib._handle+diff)
fptr = (C.c_uint).from_address(lib._handle+diff)
fptr.value = memptr
d = np.ones((5)).astype('double')
lib.init()
lib.fun(d.ctypes.data_as(C.POINTER(C.c_double)), C.c_size_t(5))
print d
c
c
#包括
#包括
#包括
外部“C”BOOL WINAPI\u CRT\u INIT(HINSTANCE hinstDLL、DWORD fdreason、LPVOID lpReserved);
外部“C”\u declspec(dllexport)
虚无乐趣(双倍*数据,大小){
双*数据=(双*)数据V;
int i;
对于(i=0;i
将.exe
文件视为.dll
似乎有点荒谬。DLL的存在有很好的理由,它们与EXE的不同也有很好的理由。而“修复”问题所涉及的工作量在很大程度上说明了为什么试图让一方做另一方的工作是。。。好吧,如果不是徒劳的练习,是挫折的练习,有点毫无意义。AFAICS,您不能单独运行EXE;它必须从Python运行。这完全违背了EXE的功能。
import numpy as np
import ctypes as C
import pefile
def unprotect( address):
crap = C.byref(C.create_string_buffer("\x00"*4))
res = C.windll.kernel32.VirtualProtect(address, 0x1000, 0x40, crap)
lib = C.cdll.LoadLibrary('pycon.exe')
k32 = C.windll.kernel32
pe = pefile.PE('pycon.exe')
for entry in pe.DIRECTORY_ENTRY_IMPORT:
#print entry.dll
#assuming that the exe only has dependency on kernel32
for imp in entry.imports:
diff = imp.address-0x400000
memptr = k32.GetProcAddress(k32._handle,imp.name)
unprotect(lib._handle+diff)
fptr = (C.c_uint).from_address(lib._handle+diff)
fptr.value = memptr
d = np.ones((5)).astype('double')
lib.init()
lib.fun(d.ctypes.data_as(C.POINTER(C.c_double)), C.c_size_t(5))
print d
#include <stdio.h>
#include <math.h>
#include <windows.h>
extern "C" BOOL WINAPI _CRT_INIT(HINSTANCE hinstDLL, DWORD fdwReason, LPVOID lpReserved);
extern "C" __declspec(dllexport)
void fun(double *datav, size_t size) {
double * data = (double *) datav;
int i;
for (i = 0; i < size; ++i)
{
data[i] = 1.7159*tanh(0.66666667*data[i]);
printf("workign! %f\n",data[i]);
}
fflush(stdout);
}
extern "C" __declspec(dllexport)
void init() {
_CRT_INIT(NULL,DLL_PROCESS_ATTACH,NULL);
}
BOOL APIENTRY DllMain( HMODULE hModule,
DWORD ul_reason_for_call,
LPVOID lpReserved
)
{
_CRT_INIT(NULL,DLL_PROCESS_ATTACH,NULL);
printf("main exe");
return TRUE;
}