讲解Python在Windows和Linux下调用动态链接库的教程。
什么是动态链接库?
动态链接库(Dynamic Link Library,简称DLL)是一种可重用的程序代码解决方案。在Windows操作系统中,大量的Windows API都是通过DLL的形式提供给应用程序的。Linux操作系统中,相类似的动态链接库则被称为共享对象(Shared Object,简称SO)。
为什么要使用动态链接库?
使用动态链接库有以下几个优点:
- 节约内存。不同的程序可能需要调用同一段代码,而动态链接库只需要被加载一次,就可以供多个程序使用。
- 维护方便。当需要更新某个函数或者修改某个bug时,只需要更新一份动态链接库,而不需要更新所有使用该函数的程序。
- 提高安全性。动态链接库的代码被封装在一个单独的文件中,不同的程序都只是调用而非拥有代码,有利于防止恶意程序篡改代码。
Python中调用动态链接库的方法
Windows
加载dll
在Windows平台上,调用动态链接库需要使用ctypes模块。下面是一个加载DLL并调用其中函数的例子:
import ctypes
# 加载dll
mylib = ctypes.windll.LoadLibrary('mylib.dll')
# 调用dll中的函数
result = mylib.add(1, 2)
print(result)
在上述代码中,我们首先用ctypes.windll.LoadLibrary()
函数加载了名为mylib.dll
的动态链接库,然后使用.add()
方法计算了1+2的结果,并将其打印出来。
定义函数类型
有时候,需要通过ctypes定义函数类型才能够调用某些函数.比如下面的例子:
import ctypes
# 加载dll
mylib = ctypes.windll.LoadLibrary('mylib.dll')
# 定义函数类型
my_function = ctypes.WINFUNCTYPE(
ctypes.c_int, ctypes.c_int, ctypes.c_int
)
# 获取dll中的函数
add = my_function(('add', mylib))
# 调用函数
result = add(1, 2)
print(result)
在上述代码中,我们使用ctypes.WINFUNCTYPE()
函数定义了一个函数类型 my_function
。该类型的参数为三个整型参数,返回值为整型。然后我们使用my_function()
函数获取了dll
中的add()
函数,并在最后调用了该函数。
Linux
加载so
在Linux平台上,调用动态链接库也需要使用ctypes模块。和在Windows平台上类似,不同之处在于需要使用.LoadLibrary()
函数加载共享对象(so)文件:
import ctypes
# 加载so
mylib = ctypes.cdll.LoadLibrary('mylib.so')
# 调用so中的函数
result = mylib.add(1, 2)
print(result)
在上述代码中,我们首先使用.cdll.LoadLibrary()
函数加载了名为mylib.so
的共享对象文件,然后使用.add()
方法计算了1+2的结果,并将其打印出来。
定义函数类型
同样的,在Linux平台上也会有需要定义函数类型才能够调用某些函数的情况。下面是一个调用dlopen()
函数的例子:
import ctypes
# 加载so
mylib = ctypes.cdll.LoadLibrary('mylib.so')
# 定义函数类型
my_function = ctypes.CFUNCTYPE(
ctypes.c_int, ctypes.c_int, ctypes.c_int
)
# 获取so中的函数
add = my_function(('add', mylib))
# 调用函数
result = add(1, 2)
print(result)
在上述代码中,我们首先使用.cdll.LoadLibrary()
函数加载了名为 mylib.so
的共享对象文件。然后定义了函数类型my_function
和获取了so中的 add()
函数,最后调用了该函数。
示例
下面是两个示例,一个是调用Windows
下的dll
文件,另一个是调用Linux
下的so
文件。
Windows下的dll:
-
首先,我们先在C语言中编写一个函数,在Visual Studio中编译成dll文件:
c
__declspec(dllexport) int add(int a, int b) {
return a + b;
} -
保存为
mylib.c
文件,并将其编译成dll文件。打开Visual Studio,创建一个新的Win32 Console Application
,在空白的main()函数中添加mylib.c
文件中的代码,然后调用Build -> Build Solution
编译产生dll文件。 -
将产生的
mylib.dll
文件拷贝到Python解释器所在的文件夹中。然后在Python中加载dll,并调用其中函数:```python
import ctypes加载dll
mylib = ctypes.windll.LoadLibrary('mylib.dll')
调用dll中的函数
result = mylib.add(1, 2)
print(result)
```
Linux下的so:
-
首先,我们先在C语言中编写一个函数,在Linux系统中编译成so文件:
```c
include
int add(int a, int b) {
return a + b;
}int main() {
printf("hello world");
return 0;
}
``` -
保存为
mylib.c
文件,并将其编译成so文件。在命令行中使用下面的命令进行编译:sh
gcc -shared -fPIC -o mylib.so mylib.c -
将产生的
mylib.so
文件拷贝到Python解释器所在的文件夹中。然后在Python中加载so,并调用其中函数:```python
import ctypes加载so
mylib = ctypes.cdll.LoadLibrary('./mylib.so')
调用so中的函数
result = mylib.add(1, 2)
print(result)
```
以上便是Python在Windows和在Linux下调用动态链接库的详细攻略,希望能对你有所帮助!
本站文章如无特殊说明,均为本站原创,如若转载,请注明出处:Python在Windows和在Linux下调用动态链接库的教程 - Python技术站