我有一个共享库 (DLL),我正在将其导入到 Python 脚本中,我可以调用函数,但无法写入全局变量。我使用“memset”传递全局变量的地址、数据和变量的大小(在这种情况下为 4 个字节,因为该全局变量是一个整数),但当我尝试读取全局变量时,它总是显示输出为 0(零)。有人能帮我吗?如何使用 Python 将数据设置为共享库中的全局变量?
在使用 Python 调用共享库(DLL)时,正确处理全局变量需要确保你正在正确地访问和修改共享库中的内存。由于共享库中的全局变量是在库加载时初始化的,你必须正确地将它们传递给 Python 并确保它们的数据更新。
你提到尝试使用 memset 来修改全局变量,但 memset 只会填充内存并将数据清零,而无法像你所期望的那样修改共享库中的全局变量。要在 Python 中成功地修改共享库的全局变量,你需要确保以下几点:
memset
ctypes
cffi
Python 提供了 ctypes 库来与共享库进行交互。通过 ctypes,你可以调用共享库中的函数,并直接操作内存中的全局变量。
假设你有一个名为 mydll.dll 的共享库,并且其中包含一个全局变量 global_var 和一个函数 set_global_var 来修改它。
mydll.dll
global_var
set_global_var
#include <stdio.h> int global_var = 0; // 定义一个全局变量 void set_global_var(int value) { global_var = value; // 修改全局变量 } int get_global_var() { return global_var; // 获取全局变量 }
使用这个代码,编译一个共享库(例如,mydll.dll)。
在 Python 中,你可以使用 ctypes 库来加载 DLL,并通过传递指针直接操作全局变量。
import ctypes # 加载 DLL mydll = ctypes.CDLL('mydll.dll') # 定义全局变量的数据类型(假设它是一个整数) global_var_ptr = ctypes.pointer(ctypes.c_int(0)) # 初始化为 0 # 获取当前全局变量的值 print(f"Before: {global_var_ptr.contents.value}") # 调用 DLL 中的 set_global_var 函数来修改全局变量 mydll.set_global_var(42) # 获取修改后的全局变量的值 print(f"After: {global_var_ptr.contents.value}") # 如果你有一个函数来获取全局变量的值,可以直接调用它 mydll.get_global_var.restype = ctypes.c_int # 设置返回类型 result = mydll.get_global_var() # 获取值 print(f"Global Var (via get): {result}")
ctypes.CDLL('mydll.dll')
ctypes.pointer(ctypes.c_int(0))
global_var_ptr.contents.value
get_global_var
类型不匹配:确保在 ctypes 中创建的变量类型与你在 C 代码中定义的类型匹配。如果 global_var 是 int,你应当使用 ctypes.c_int。
int
ctypes.c_int
指针访问问题:在访问或修改全局变量时,请确保你传递的是正确的指针。如果全局变量是一个简单的整数,可以直接通过 ctypes.pointer(ctypes.c_int(...)) 传递指针。
ctypes.pointer(ctypes.c_int(...))
全局变量作用域:在 C 中,全局变量的作用域是整个程序。确保你没有错误地重新定义或覆盖了全局变量的地址。
DLL 加载问题:确保你的共享库路径正确。如果你使用的是 Windows 系统,.dll 文件需要放在合适的路径下,或者使用绝对路径来加载它。
.dll
通过使用 ctypes,你可以轻松地将数据设置为共享库中的全局变量,并避免手动修改内存。