祝各位道友念头通达
GitHub Gitee 语雀 打赏

Python调用C语言采坑,window和linux

场景

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编译动态链接库, 问题解决

posted @ 2022-01-26 13:21  韩若明瞳  阅读(328)  评论(0编辑  收藏  举报