Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/python/316.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/0/windows/16.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Python ctypes加载dll库时不会出错,但在函数调用时不会返回预期结果_Python_Windows_Ctypes - Fatal编程技术网

Python ctypes加载dll库时不会出错,但在函数调用时不会返回预期结果

Python ctypes加载dll库时不会出错,但在函数调用时不会返回预期结果,python,windows,ctypes,Python,Windows,Ctypes,我试图在反病毒供应商的serverapi.dll周围编写一个Python 3.8.2包装器,这会让我的手变得脏兮兮的。它们提供了一些C代码片段,展示了如何在C/C++中使用它,我正在尝试将这些代码改编成Python C类型。我无法控制DLL——我只能加载它并尝试调用函数。我已经将他们的代码粘贴到VisualStudio中,对其进行编译,然后看着它按照他们的说法返回 我要修改的供应商代码: HMODULE hMod = LoadLibrary(L"ServerApi.dll")

我试图在反病毒供应商的serverapi.dll周围编写一个Python 3.8.2包装器,这会让我的手变得脏兮兮的。它们提供了一些C代码片段,展示了如何在C/C++中使用它,我正在尝试将这些代码改编成Python C类型。我无法控制DLL——我只能加载它并尝试调用函数。我已经将他们的代码粘贴到VisualStudio中,对其进行编译,然后看着它按照他们的说法返回

我要修改的供应商代码:

HMODULE hMod = LoadLibrary(L"ServerApi.dll");
if (!hMod)
{
    std::cout << "Cannot load library error. Last error is:" << GetLastError() << std::endl;
    return 1;
}
era_init_lib init_lib = (era_init_lib)GetProcAddress(hMod, "era_init_lib");
if (!init_lib)
{
    std::cout << "Cannot init library" << std::endl;
    FreeLibrary(hMod);
    return 1;
}
...
int res = init_lib();
if (res)
{
    std::cout << "Init lib result:" << res << std::endl;
    FreeLibrary(hMod);
    return 1;
}
我的肾盂尝试:

from ctypes import *

serverapi = WinDLL('../lib/ServerApi.dll')
era_init = serverapi.era_init_lib
era_init.restype = c_int
era_init.argtypes = None

res = era_init()
print("init code: " + str(res)) // prints "init code: 2"
我尝试的问题是,它运行时没有Python错误,但返回代码错误。当我编译上面的C代码时,era_init_lib()会返回它应该返回的0,并且库已经准备好使用了。当我运行python代码时,它运行的代码是2。根据本模块的稀疏文档,可能的返回代码为:

Return value:
ERA_SUCCESS                     0
ERA_INVALID_ARGUMENT            1
ERA_NOT_INITIALIZED             3
列表中可疑地缺少了2,这使我相信Python错误地加载了这个库

我尝试过的事情:

  • 我认为这是一个Windows调用约定DLL,但我尝试用CDLL加载它。没有更改,没有python错误/堆栈跟踪/相同的返回代码
  • 我已经验证了DLL是x64,我的Python解释器是x64
  • 我让procmon在python代码执行时运行。它似乎像我初步理解的那样加载了所有依赖DLL
  • 我试图包装C代码用来加载它的函数。没有用,但尝试如下:
  • 我尝试了以下功能的原型,但没有成功:
TL;DR:与C代码一样工作,但Python Ctypes函数调用的行为与预期不符


有人知道下一步要去哪里吗?

在x64中只有一个调用约定
windle
CDLL
是相同的。你的方法没有错。procmon是否显示加载了相同的DLL,pathwise?很高兴知道!有点像是在ProcMon前线。VisualStudio在程序执行时按顺序提供DLL加载列表。我对照ProcMon检查了这个列表,看起来这个列表有问题。Python代码在尝试serverapi.dll之前加载ws2_32.dll。C代码首先加载serverapi.dll,然后加载ws2_32.dll。深入研究ProcMon,我检查了它的日志末尾,C代码中加载的所有内容都已加载并附加到python.exe进程。这两种语言中的路径总是相同的——对于大多数语言,都是C:\windows\system32them@MarkTolonen在你问起ProcMon之后,我仔细查看了结果。我注意到serverapi.dll依赖于一个network.dll,它只能查看C:\Python\Python38\network.dll。它不会搜索系统路径或项目位置。出于好奇,我把network.dll放在上面的路径上,一切正常!现在的问题是如何让它正确地搜索路径,以便与其他项目文件一起找到它。欢迎使用DLL地狱:)我想知道为什么Python38目录中有network.DLL。我的安装没有。x64中只有一个调用约定
windl
CDLL
是相同的。你的方法没有错。procmon是否显示加载了相同的DLL,pathwise?很高兴知道!有点像是在ProcMon前线。VisualStudio在程序执行时按顺序提供DLL加载列表。我对照ProcMon检查了这个列表,看起来这个列表有问题。Python代码在尝试serverapi.dll之前加载ws2_32.dll。C代码首先加载serverapi.dll,然后加载ws2_32.dll。深入研究ProcMon,我检查了它的日志末尾,C代码中加载的所有内容都已加载并附加到python.exe进程。这两种语言中的路径总是相同的——对于大多数语言,都是C:\windows\system32them@MarkTolonen在你问起ProcMon之后,我仔细查看了结果。我注意到serverapi.dll依赖于一个network.dll,它只能查看C:\Python\Python38\network.dll。它不会搜索系统路径或项目位置。出于好奇,我把network.dll放在上面的路径上,一切正常!现在的问题是如何让它正确地搜索路径,以便与其他项目文件一起找到它。欢迎使用DLL地狱:)我想知道为什么Python38目录中有network.DLL。我的安装没有它。
Return value:
ERA_SUCCESS                     0
ERA_INVALID_ARGUMENT            1
ERA_NOT_INITIALIZED             3
from ctypes import *
from ctypes import wintypes

windll.kernel32.GetProcAddress.argtypes = [wintypes.HMODULE, wintypes.LPCSTR]
windll.kernel32.GetProcAddress.restype = WINFUNCTYPE(c_int)
init_lib = windll.kernel32.GetProcAddress(wdll, "era_init_lib".encode("cp1252"));
init_lib.restype = c_int

print(str(init_lib())) // Prints "2"
era_init_proto = WINFUNCTYPE(c_int)
era_init = era_init_proto(("era_init_lib", serverapi), None)