场景
python使用pyside6(Qt6)做一个简单的界面, 通过udp socket 向fpga程序发送接收udp协议数据包, 需要对协议进行解析, 过滤,再显示到界面上
分析:
1.协议解析使用C语言比较高效
2.python 语言写pyside6比较方便简单
需要将二者结合, python 调用 C 语言,所以 C需要编译成.dll(windows)或.so(linux)提供给python程序调用,当然c和c++,java等都可以调用.dll,.so的动态链接库
步骤
编写 test.c
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
int main(int argc, char const *argv[])
{
printf("good \n");
return 0;
}
int getInfo(unsigned char **data) {
printf("test adskfakdfkla \n");
*data = (unsigned char *) malloc(100);
memset(data, 0, 100);
unsigned char * ptr = "hello world! \n";
memcpy(data, ptr, strlen(ptr));
printf("getInfo \n");
return 10;
}
int getInfo1() {
printf("test adskfakdfkla \n");
return 10;
}
int getInfo2(int a) {
return a;
}
int getInfo3(char *ptr) {
char *tar = "hello world, mis han";
return memcmp(tar, ptr, 10);
}
int getInfo4(char *ptr, unsigned char **tar) {
*tar = (unsigned char *)malloc(100);
memset(*tar, 0, 100);
char * cc = "hello world, mis han";
memcpy(*tar, cc, strlen(cc));
// memcpy(*tar+3, ptr, 10);
return memcmp(tar, ptr, 10);
}
int cfree(char *tar) {
free(tar);
}
windows编译 dll, liunx 编译 .so
gcc test.c -shared -o Test.dll //win
gcc test.c -shared -o Test.so //mac or linux
python 程序
# -*- coding: utf-8 -*-
import os
from ctypes import *
# 开发环境
cpath = os.path.dirname(__file__) + "\\Test.dll" #window 获取.dll的所在目录
#cpath = os.path.dirname(__file__) + "\\Test.so" #linux 获取.so的所在目录
print(cpath)
UnicastClient = cdll.LoadLibrary(cpath)
print("验证调用方法: ")
a = UnicastClient.getInfo1()
print(a)
print("验证传值: ")
b = UnicastClient.getInfo2(c_int(11))
print("验证传递指针: ")
print(b)
print(UnicastClient.getInfo3(create_string_buffer(b"hello world, mis han")))
print(UnicastClient.getInfo3(create_string_buffer(b"hcllo world, mis han")))
print("验证malloc: ")
rdata = pointer(c_char())
print(UnicastClient.getInfo4(create_string_buffer(b"hello world, mis han"), byref(rdata)))
rdata1 = pointer(c_char())
print(UnicastClient.getInfo4(create_string_buffer(b"hcllo world, mis han"), byref(rdata1)))
print(string_at(rdata))
UnicastClient.cfree(rdata)
UnicastClient.cfree(rdata1)
碰见的问题
OSError: [WinError 193] %1 不是有效的 Win32 应用程序
在window(64位)环境下执行代码 调用 cdll.LoadLibrary(path) 的时候报这个错误
1.python下载的版本是32位还是64位
2.gcc在win下编译的是dll,不是.so
3.gcc本身的版本是32位还是64位
上述问题是由第3个, mingw是32位版本的程序,64位下载地址: https://udomain.dl.sourceforge.net/project/mingw-w64/Toolchains targetting Win64/Personal Builds/mingw-builds/8.1.0/threads-win32/seh/x86_64-8.1.0-release-win32-seh-rt_v6-rev0.7z
解压之后, 将 E:\x86_64-8.1.0-release-win32-seh-rt_v6-rev0\mingw64\bin
mingw64所在bin的路径配置在全局环境当中, 然后在使用gcc编译动态链接库, 问题解决