python3中ctypes的简单使用


写在前面

闲来无事,学习一下使用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");
    }
}