py cdll

这是一个vc++的动态库 Csp.dll,基于python3.12 ,给我一个简单的python调用例子,依次调用这三个接口 DLL_EXPORT int __stdcall CPTInitExV2 (char* LocalIP, char* DeviceType, char* RegionCode, unsigned char** out); DLL_EXPORT HANDLE __stdcall CPTCommConnect (char *strIp, char *strExtend, FUNCTION CallFun, UINT iUser); DLL_EXPORT int __stdcall CMDCheckParam(HANDLE handle, char *strData, int iLeng, FUNCTION pCallBack, UINT iUser); typedef int (__stdcall *FUNCTION)(HANDLE handle, UINT rtn, UINT iEx, char * strMess , UINT iUser);

import ctypes
from ctypes import wintypes
from ctypes import *
import time
import os

# 1. 加载 DLL
# 请确保 Csp.dll 在当前目录下,或者填写绝对路径
try:
    csp_dll = ctypes.CDLL('./CspProductTool.dll')
except OSError as e:
    print(f"加载 DLL 失败: {e}")
    exit(1)

# 2. 定义回调函数类型 FUNCTION
# typedef int (__stdcall *FUNCTION)(HANDLE handle, UINT rtn, UINT iEx, char * strMess , UINT iUser);
# HANDLE 通常等同于 void* (ctypes.c_void_p)
# UINT 等同于 ctypes.c_uint
# char* 等同于 ctypes.c_char_p
FUNCTION_TYPE = ctypes.WINFUNCTYPE(
    ctypes.c_int,           # 返回值 int
    ctypes.c_void_p,        # HANDLE handle
    ctypes.c_uint,          # UINT rtn
    ctypes.c_uint,          # UINT iEx
    ctypes.c_char_p,        # char * strMess
    ctypes.c_uint           # UINT iUser
)

# 3. 定义回调函数的具体实现
def my_callback_function(handle, rtn, iEx, strMess, iUser):
    print(f"--- 回调触发 ---")
    print(f"Handle: {handle}")
    print(f"Return Code: {rtn}")
    print(f"Ex Info: {iEx}")
    # 注意:strMess 可能是 bytes,需要解码
    msg = strMess.decode('gbk') if strMess else "None" # 假设是 GBK 编码,如果是 UTF-8 请改为 'utf-8'
    print(f"Message: {msg}")
    print(f"User Data: {iUser}")
    return 0 # 返回 0 表示成功,具体看文档要求

# 将 Python 函数转换为 C 函数指针
c_callback = FUNCTION_TYPE(my_callback_function)

# ==========================================
# 接口 1: CPTInitExV2
# ==========================================
# int __stdcall CPTInitExV2 (char* LocalIP, char* DeviceType, char* RegionCode, unsigned char** out);
'''
csp_dll.CPTInitExV2.argtypes = [
    ctypes.c_char_p,        # LocalIP
    ctypes.c_char_p,        # DeviceType
    ctypes.c_char_p,        # RegionCode
    ctypes.POINTER(ctypes.c_char_p) # unsigned char** out (这里用 char* 模拟 byte 指针)
]
csp_dll.CPTInitExV2.restype = ctypes.c_int
'''
print(">>> 调用 CPTInitExV2...")
# 准备参数
local_ip = b"192.168.1.100"           # 使用 bytes
device_type = b"F663NV3a"
region_code = b"0"
out_data = ctypes.c_char_p()     # 用于接收输出指针


out_data = (c_char_p * 1)()
c_chara3 = (c_char* 512)()
#c_chara.value = bytes('11',encoding='utf-8')
out_data[0] = c_char_p(c_chara3.value)

# 调用
# 注意:这里传的是 ctypes.byref(out_data),因为函数需要 char**
ret_init = csp_dll.CPTInitExV2(local_ip, device_type, region_code, ctypes.byref(out_data))


if ret_init == 0: # 假设 0 是成功
    
    print(f"CPTInitExV2 返回: {ret_init}")
    print(out_data,out_data[0])
    # print(f"输出数据内容: {out_data.value}") # 二进制数据可能打印出来很乱
else:
    print("初始化失败,停止后续调用。")
    exit(1)

# ==========================================
# 接口 2: CPTCommConnect
# ==========================================
# HANDLE __stdcall CPTCommConnect (char *strIp, char *strExtend, FUNCTION CallFun, UINT iUser);

time.sleep(1) 

csp_dll.CPTCommConnect.argtypes = [
    ctypes.c_char_p,        # strIp
    ctypes.c_char_p,        # strExtend
    FUNCTION_TYPE,          # CallFun (回调函数)
    ctypes.c_uint           # iUser
]
csp_dll.CPTCommConnect.restype = ctypes.c_void_p # HANDLE

print("\n>>> 调用 CPTCommConnect...")
ip_addr = b"192.168.1.1"
extend_info = b"MATTelnetConnect=telnetUser:xxx@@telnetPass:xxx"
user_param = 0

# 调用
h_handle = csp_dll.CPTCommConnect(ip_addr, extend_info, c_callback, user_param)

print(f"连接句柄 Handle: {h_handle}")
if not h_handle:
    print("连接失败,句柄为空。")
    exit(1)

# ==========================================
# 接口 3: CMDCheckParam
# ==========================================
# int __stdcall CMDCheckParam(HANDLE handle, char *strData, int iLeng, FUNCTION pCallBack, UINT iUser);

csp_dll.CMDCheckParam.argtypes = [
    ctypes.c_void_p,        # HANDLE handle
    ctypes.c_char_p,        # strData
    ctypes.c_int,           # iLeng
    FUNCTION_TYPE,          # pCallBack
    ctypes.c_uint           # iUser
]
csp_dll.CMDCheckParam.restype = ctypes.c_int

time.sleep(1) 
print("\n>>> 调用 CMDCheckParam...")
check_data = b"UserName=user|"
data_len = len(check_data)

# 调用
ret_check = csp_dll.CMDCheckParam(h_handle, check_data, data_len, c_callback, user_param)

print(f"CMDCheckParam 返回: {ret_check}")

print("\n--- 调用结束 ---")

seconds = 10
while seconds > 0:
    print(seconds)
    time.sleep(1) # 暂停1秒
    seconds -= 1
print("倒计时结束")

 

posted @ 2026-04-14 15:12  cnchengv  阅读(10)  评论(0)    收藏  举报