接口测试 使用 Python 测试 DLL/SO 动态链接库接口

wuhao for 郑州软件测试圈 · 2018年03月22日 · 最后由 lion 回复于 2018年04月25日 · 4179 次阅读
本帖已被设为精华帖!

1. 背景与需求

  1. 公司通过提供C/C++语言开发的DLL/SO动态链接库,向第三方提供接口服务,需要对此进行测试。
  2. 测试人员普遍不具备C语言能力,但可以使用Python语言解决问题

2. 基础知识

  1. 动态链接库在Windows中为.dll文件,在linux中为.so文件,使用C/C++进行编写。
  2. 通过Python调用C语言接口时,可以使用Python提供的ctypes模块调用C接口
  3. ctypes 是一个为 Python 准备的内建函数库。无需安装可直接使用。它提供兼容C的数据类型,并允许调用DLL或SO库中的函数。
  4. 每一个C语言的参数,都不能直接使用Python直接定义的类型,均需使用ctypes提供的类型进行定义

3. 调用方法

1. 使用Python加载.so库文件

from ctypes import *
os.chdir('/home/wuhao/eclipse-workspace/yunhsm_SDK_Test/data/')
sdkPath = os.getcwd()
cur = cdll.LoadLibrary(sdkPath + "/libtestapi.so")
return cur

2. 使用Python调用.so中的方法

self.uiLength = c_int(8)     
self.random = (c_ubyte*self.uiLength.value)()
self.ret_generateRandom = cur.SDF_GenerateRandom(self.uiLength, self.random)
print "ret_generateRandom: " + str(self.ret_generateRandom)

3. 使用Python的ctypes模块,定义几种C中常用数据类型

A = (c_ubyte*8)() 对应C中的unsigned char类型
B = (c_ubyte*3)(1,2,3) 对应C中的unsigned char类型
C = c_uint(8) 对应C中的unsigned int类型
D = c_void_p 对应C中的void类型

Python调用ctypes数据格式 意义 C中数据结构
A = (c_ubyte*8)() 用Python定义一个长度为8的数组,数组中内容默认赋值全0 对应C中的unsigned char类型
B = (c_ubyte*3)(1,2,3) 用Python定义一个长度为3的数组,数组中内容为1,2,3 对应C中的unsigned char类型
C = c_uint(8) 定义一个int型变量,值为8 对应C中的unsigned int类型
D = c_void_p 定义一个void型变量 对应C中的void类型

4. 使用Python定义C中结构体

  1. C中结构体
-typedf struct ECCrefPublicKey_st{
unsigned int bits;
unsigned char K[ECCref_MAX_LEN]
}ECCrefPrivateKey
  1. Python中定义C结构体
from ctypes import *
from ctypes import c_ubyte
from ctypes import c_int
class ECCrefPublicKey(Structure):
_fields_ = [("bits", c_uint),
("K", c_ubyte*64)]

5. 使用Python传入C中结构体类型参数(传入的实质为结构体的指针)

  1. C中需传入结构体参数的接口:
int SDF_ExternalVerify_ECC(
    void *hSessionHandle,
    ECCrefPublicKey *pucPublicKey,
)

2.Python中传入结构体参数的方法:

self.eccPublicKey = ECCrefPublicKey()
self.ret_ExternalVerifyECC = self.cur.SDF_ExternalVerify_ECC(hSessionHandle, byref(self.eccPublicKey))

6. 使用Python传入C中指针类型参数

  1. C中需传入指针参数的接口:
int SDF_OpenDevice(void **phDeviceHandle);
  1. Python中传入指针参数的方法:
self.hDeviceHandle = c_void_p(0)
self.ret_OpenDevice = self.cur.SDF_OpenDevice(byref(self.hDeviceHandle))

3. 总结

目前使用ctypes模块和以上数据类型,能够满足工作中对动态链接库的接口测试需求,如果工作中涉及到了新得数据类型,后续也会继续进行补充,希望可以帮到大家。

如果觉得我的文章对您有用,请随意打赏。您的支持将鼓励我继续创作!
共收到 2 条回复 时间 点赞
seveniruby 将本帖设为了精华贴 03月22日 17:09

会了java学习c就很简单了,我最近就在学习c++😂 ,还是赞楼主的idea~~~~

swig、boost python 这个都提供了较好的封装;可以搞下

需要 登录 后方可回复, 如果你还没有账号请点击这里 注册