前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >python高阶教程-调用win c/c++ dll文件

python高阶教程-调用win c/c++ dll文件

作者头像
羽翰尘
修改2019-11-26 17:00:58
3.1K0
修改2019-11-26 17:00:58
举报
文章被收录于专栏:技术向技术向

本文由腾讯云+社区自动同步,原文地址 https://cloud.tencent.com/developer/article/1540893

本篇内容来自原创小册子《python高阶教程》

背景

某些情况下,我们需要python与其他编程语言,如c/c++联合运行,以获得额外的性能或者功能。比如,将

经常调用的业务逻辑用c重写一遍,提高效率;或者重复利用已经开发好的dll库,缩短开发周期。

两种调用c/c++库的方式

  1. __stdcall方式

在python中通过dll = ctypes.WinDLL("TestDll.dll")调用

  1. __cdecl方式

在python中通过dll = ctypes.cdll.LoadLibrary("TestDll.dll")调用

具体使用了哪种方式需要看源码,如果不知道源码,可以两种方式都试试,错误的调用方式会

出现以下ValueError.

ValueError: Procedure called with not enough arguments (8 bytes missing) or wrong calling convention

查看dll中的函数名称

实际上,编译器会修改函数的名称。虽然可以通过.def文件来禁止编译器做修改,但是尚未发现在MinGW上如果操作。在本文中使用Dependency Walker(depends)软件读取dll中的函数列表,获取函数名称。

下载地址

简单Demo

1.TestDll.h文件

#ifdef __cplusplus
extern "C"{
#endif
int __stdcall __declspec(dllexport) MyAdd(int nA, int nB);
 
#ifdef __cplusplus
}
#endif

2.TestDll.cpp文件

#include "TestDll.h"
 
#ifdef __cplusplus
extern "C"{
#endif
int __stdcall __declspec(dllexport) MyAdd(int nA, int nB)
{
    return nA + nB;
}
#ifdef __cplusplus
}
#endif

3.TestDll.bat编译脚本

gcc TestDll.cpp -shared -o TestDll.dll

4.TestDll.py调用

import ctypes
 
# 导出函数是__stdcall声明的使用
dll = ctypes.WinDLL("TestDll.dll")
# 导出函数是__cdecl声明的使用
#dll = ctypes.cdll.LoadLibrary("TestDll.dll")

summmm = getattr(dll, 'MyAdd@8')
ret = summmm(2, 4)
print(ret)

运行后会看到python脚本输出了正确结果。

TODO

  1. ctypes中的c与python对象映射表
  2. 指针作为参数
本文参与 腾讯云自媒体分享计划,分享自作者个人站点/博客。
原始发表:2018-09-26,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 作者个人站点/博客 前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体分享计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 背景
  • 两种调用c/c++库的方式
  • 查看dll中的函数名称
  • 简单Demo
  • TODO
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档