写在前面
闲来无事,学习一下使用python调用动态链接库,就用到了ctypes库。
使用方法
#调用ctypes中的各类方法
from ctypes import cdll,CDLL,WinDLL,windll
#调用platform获取当前操作系统
import platform
if platform.system() == 'Windows':
#windows下调用的是msvcrt.dll文件
libc = cdll.LoadLibrary('msvcrt.dll')
elif platform.system() == 'Linux':
#Linux下调用.so文件
libc = cdll.LoadLibrary('libc.so.6')
#python3中字符串默认使用Unicode,需要将其转换为bytes
libc.printf("Hello World!\n".encode('ascii'))
#如果没有输出,请在命令行下执行py文件
gcc编译DLL
#使用gcc
gcc -shared -o filename.dll filename.c
#使用g++
g++ -shared -o filename.dll filename.cpp
#Linux下的命令
gcc -fPIC -shared filename.c -o filename.so
g++ -fPIC --share filename.cpp -o filename.so
#注意:使用g++时需要在cpp文件里加上extern "C"{},使用nm命令可查看链接库中的函数
VS2019
首先创建MFC动态链接库程序,在对应的cpp文件里写入函数,在对应的头文件里声明函数,然后在后缀为.def的文件里写入函数名,不需要分号,另外,如果python版本为32位,在Release的时候选择x86,python为64位版本则选择x64。
//在C++中调用DLL
#include<stdio.h>
#include<Windows.h>
using namespace std;
typedef int (*ApiAdd)(int, int);
int main(void)
{
int a = 3, b = 4,c = 0;
//编码格式为Unicode,“test.dll”前面需要加L(LPCTSTR)
HINSTANCE hDllInst = LoadLibrary(L"test.dll");
if (hDllInst == NULL)
{
printf("error\n");
return 0;
}
else
{
printf("Success!\n");
}
ApiAdd myfun = 0;
//这里只是为函数重命名,我写的函数是判断两个数较大的那个
myfun = (ApiAdd)GetProcAddress(hDllInst, "maxnum");
if (myfun != NULL)
{
c = myfun(a, b);
printf("%d\n", c);
//释放句柄
FreeLibrary(hDllInst);
}
else
{
printf("error\n");
}
}