python调用dll接口

介绍

如何在python中调用c dll接口。c dll接口会用到一些指针的指针,结构体,回调函数等,文章总结了一些常见用法。

.h 代码

#pragma once

#ifdef  __cplusplus
extern "C" {
#endif


#if defined(WIN32)  /* windows */
#define EXPORT_API                  __declspec(dllexport)
#else
#define EXPORT_API                  __declspec(dllimport)
#endif

	/* 函数标准调用约定 Standard function calling convention */
#ifdef i386
#ifndef STDCALL
#define STDCALL                 __attribute__((stdcall))
#endif
#else
#ifndef WIN32
#ifndef STDCALL
#define STDCALL
#endif
#else
#ifndef STDCALL
#define STDCALL                 __stdcall
#endif
#endif

#endif

/*
* 说明: 版本为x64版本,基于vs2019,使用前需要先安装依赖库 VC_redist15-17-19-22.x64.exe
* 中文编码格式为utf8
*/

#define IN
#define OUT
#define INOUT

struct ST_IMAGE
{
	int   int_type;  
	float float_type; 
	double double_type;  
	long long int64_type;
	char  char_type;
	unsigned char* ptr_type; 
};


typedef void (STDCALL *image_CallBack_PF)(ST_IMAGE stImage,void* pUser);


EXPORT_API void     STDCALL    interface_func_void();

EXPORT_API int      STDCALL    interface_func_int(int a);

EXPORT_API char*    STDCALL    interface_func_more_point(int a,IN char *pstr,IN ST_IMAGE image,INOUT ST_IMAGE *pimage);

EXPORT_API int    STDCALL    interface_func_pfunc_pvoid(void* handle,image_CallBack_PF pFunc,void *pUser);

EXPORT_API ST_IMAGE*  STDCALL    interface_func_more_ppoint(void **handle,IN ST_IMAGE *image);

#ifdef  __cplusplus
}
#endif  /* end of __cplusplus */


参考代码

# -*- coding: utf-8 -*-
#
# python 调用 dll 库的一些方法
#
from ctypes import *
import os

# 加载dll库所在路径到环境变量中
_lib_path = r'./'
os.environ['path'] = f'{_lib_path};' + os.environ['path']

_lib_interface = WinDLL(os.path.join(_lib_path,'py_load_dll.dll'))

winfun_ctype = WINFUNCTYPE

class _interface_image_(Structure):
    pass

ImageCallBackDef = winfun_ctype(None, _interface_image_, c_void_p)

_interface_image_._fields_ = [
        ('int_type',c_int32),
        ('float_type',c_float),
        ('double',c_double),
        ('int64_type',c_int64),
        ('char_type',c_char),
        ('ptr_type',POINTER(c_ubyte))
    ]

class dll_interface:
    def __init__(self):
        self._handle = _interface_image_()
        self.handle = pointer(self._handle)

    @staticmethod
    def interface_func_void():
        # void     STDCALL    interface_func_void();
        _lib_interface.interface_func_void()

    @staticmethod
    def interface_func_int(a:int)->int:
        _lib_interface.interface_func_int.restype = c_int32
        _lib_interface.interface_func_int.argtypes = (c_int32,)
        # int      STDCALL    interface_func_int(int a);
        return _lib_interface.interface_func_int(a)

    @staticmethod
    def interface_func_more_point(a:int,b:c_int32,msg:str,stImage,outImage)->str:
        p_b = byref(b)
        b_msg = msg.encode('gbk')
        p_image = byref(outImage)
        _lib_interface.interface_func_more_point.restype = c_char_p
        _lib_interface.interface_func_more_point.argtypes = (c_int32,c_void_p,c_void_p,_interface_image_,c_void_p)
        # char*    STDCALL    interface_func_more_point(int a,IN char *pstr,IN ST_IMAGE image,INOUT ST_IMAGE *pimage);
        return bytes.decode(_lib_interface.interface_func_more_point(a,p_b,b_msg,stImage,p_image))

    def interface_func_pfunc_pvoid(self,call_back_func,pUser)->int:
        _lib_interface.interface_func_pfunc_pvoid.restype = c_int32
        _lib_interface.interface_func_pfunc_pvoid.argtypes = (c_void_p,c_void_p,c_void_p)
        # int    STDCALL    interface_func_pfunc_pvoid(void* handle,image_CallBack_PF pFunc,void *pUser);
        # typedef void (STDCALL *image_CallBack_PF)(ST_IMAGE stImage,void* pUser);
        return _lib_interface.interface_func_pfunc_pvoid(self.handle,call_back_func,pUser)

    def interface_func_more_ppoint(self,image:_interface_image_)->pointer:
        _lib_interface.interface_func_more_ppoint.restype = c_void_p
        _lib_interface.interface_func_more_ppoint.argtypes = (c_void_p,c_void_p)
        # ST_IMAGE*  STDCALL    interface_func_more_ppoint(void **handle,IN ST_IMAGE *image);
        return _lib_interface.interface_func_more_ppoint(byref(self.handle),byref(image))


def image_callback(st_image,pUser):
    print("recv frame:",st_image.int_type,st_image.float_type,st_image.double,st_image.int64_type,pUser)

IMAGE_CALL_BACK_FUNC = ImageCallBackDef(image_callback)


if __name__ == "__main__":
    #
    dll_interface.interface_func_void()

    #
    print(dll_interface.interface_func_int(100))

    #
    inImage = _interface_image_()
    inImage.int_type = 1
    inImage.float_type = 1.1

    inOutImage = _interface_image_()
    inOutImage.int_type = 1
    inOutImage.float_type = 1.1

    b = c_int32(10)

    print(dll_interface.interface_func_more_point(1,b,"what",inImage,inOutImage))
    print(inOutImage.int_type)
    print(b.value)  # c_int32 --> int

    # interface_func_more_ppoint
    obj = dll_interface()

    p = obj.interface_func_more_ppoint(inImage)
    print(obj._handle.float_type)
    
    # void* 强制类型转换为_interface_image_
    stImage = cast(p,POINTER(_interface_image_)).contents
    print(stImage.int_type)

    # interface_func_more_ppoint
    obj.interface_func_pfunc_pvoid(IMAGE_CALL_BACK_FUNC,100)
  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

睡在床板下_

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值