准备动态库
使用Visual Studio 2017创建项目,如图所示,选中动态链接库后点击确定。
![](https://img.laitimes.com/img/9ZDMuAjOiMmIsIjOiQnIsIiclRnblN2XjlGcjAzNfRHLGZkRGZkRfJ3bs92YsYTMfVmepNHL0EFRPBTSU10MRpHW3BjMMBjVtJWd0ckW65UbM5WOHJWa5kHT20ESjBjUIF2X0hXZ0xCMx81dvRWYoNHLrdEZwZ1Rh5WNXp1bwNjW1ZUba9VZwlHdssmch1mclRXY39CXldWYtlWPzNXZj9mcw1ycz9WL49zROBlL1MzN4UzN0IjM1IDNwAjMwIzLc52YucWbp5GZzNmLn9Gbi1yZtl2Lc9CX6MHc0RHaiojIsJye.png)
创建好的工程如下图所示
添加Dll2.h头文件
并在头文件中输入代码:
#pragma once
#include <windows.h>
/* To use this exported function of dll, include this header
* in your project.
*/
#ifdef BUILD_DLL // 记下这个
#define DLL_EXPORT __declspec(dllexport)
#else
#define DLL_EXPORT __declspec(dllimport)
#endif
#ifdef __cplusplus
extern "C"
{
#endif
unsigned int DLL_EXPORT log2_d(unsigned int n);
long long DLL_EXPORT sum(int x, int y);
DLL_EXPORT char* reverse(char *s);
#ifdef __cplusplus
}
#endif
由于在python中只能调用C,因此需要利用extern C指示编译器将代码按C进行编译。
在Dll2.cpp文件中添加代码如下:
// Dll2.cpp: 定义 DLL 应用程序的导出函数。
#include "stdafx.h"
#define BUILD_DLL //此处需要进行宏定义,名称和头文件中保持一致,且需要在includet头文件之前。
#include "Dll2.h"
#include <stdio.h>
unsigned int DLL_EXPORT log2_d(unsigned int n) {
unsigned int result = 0; unsigned int cp = n;
if (n & 0xffff0000) { result += 16; n >>= 16; }
if (n & 0x0000ff00) { result += 8; n >>= 8; }
if (n & 0x000000f0) { result += 4; n >>= 4; }
if (n & 0x0000000c) { result += 2; n >>= 2; }
if (n & 0x00000002) { result += 1; n >>= 1; }
if (cp > 1 << result) result++;
return result;
}
long long DLL_EXPORT sum(int x, int y) {
return x + y;
}
DLL_EXPORT char* reverse(char* s){ # python调用dll使用的库ctypes不支持string,因此需要使用char*
char t,
*p = s,
*q = (s + (strlen(s) - 1));
while (p < q){
t = *p;
*p++ = *q;
*q-- = t;
}
return (s);
}
查看python位数,我的是64位的,在使用Visual Studio编译动态库时要和python位数一致。
编译动态库
在工程目录下找到编译生成的动态库文件。
Python调用动态库
用python的ctypes,调用动态库
创建一个python测试文件,并将Dll2.dll文件拷贝到和python测试文件同个目录下,如图。
调用动态库里的函数需要指定参数的输入类型和返回类型,参数类型名也有所不同,下图是参数类型名对照表。
from ctypes import *
import ctypes
dllPath = ctypes.cdll.LoadLibrary("Debug/Dll2.dll")
x = 100
y = 200
print(dllPath.sum(x, y))
n = 1024
print(dllPath.log2_d(n))
dllPath.reverse.argtypes = [c_char_p] // 指定参数的输入类型
dllPath.reverse.restype = c_char_p // 返回类型
s = b"hello world" // 注意此处字符串要改成二进制
print(dllPath.reverse(s))
print(bytes.decode(dllPath.reverse(s)))
测试结果如下所示