linux 下python 调用c++的动态库的方法

Linux下python 调用c++动态库的方法

1.1 简单快速的demo

创建一个 example.cpp的源文件

cpp 复制代码
// example.cpp
extern "C" {
    void hello() {
        printf("Hello from C++!\n");
    }
}

编译产生动态库

g++ -shared -fPIC example.cpp -o libexample.so

python 调用该库

python 复制代码
import ctypes
 
# 加载动态库
lib = ctypes.CDLL('./libexample.so')
# 调用函数
lib.hello()

1.2 复杂传参数的方法

参考链接:https://zhuanlan.zhihu.com/p/466169852 指针类的传入传出

可以直接使用的demo,实现的功能为使用python传入一张图像,使用c++处理后,得到图像处理后的图像传送给python。创建一个cpp的内容如下:

cpp 复制代码
// imageprocessor.c
#include <opencv2/opencv.hpp>
#include <iostream>
#include <string>

extern "C" {
    // 函数声明,用于处理图像并返回图像数据
    void processimage(unsigned char* inputdata, int height, int width, int channels, unsigned char** outputdata, int* outputsize);
}

void processimage(unsigned char* inputdata, int height, int width, int channels, unsigned char** outputdata, int* outputsize) {
    // 从输入数据创建OpenCV图像
    cv::Mat inputimage(height, width, CV_8UC(channels), inputdata);
    std::string outputPath = "/home/ema/zzh/000000input.bmp"; 
    imwrite(outputPath,inputimage);

    // 处理图像
    cv::Mat processedimage;
    cv::cvtColor(inputimage, processedimage, cv::COLOR_BGR2GRAY); // 示例处理:转换为灰度图像

    // 分配输出数据内存
    *outputsize = processedimage.total() * processedimage.elemSize();
    *outputdata = new unsigned char[*outputsize];
    std::memcpy(*outputdata, processedimage.data, *outputsize);

}

// 注意:需要提供一个函数来释放由C代码分配的内存
extern "C" {
    void free_memory(unsigned char* data);
}

void free_memory(unsigned char* data) {
    delete[] data;
}

编译文件的内容为,使用该文件可以编译成动态库。

bash 复制代码
cmake_minimum_required(VERSION 3.0.0)
project(HalconDemo VERSION 0.1.0)
 
set(TARGET_NAME HalconDemo)
 
set(CMAKE_CXX_STANDARD 11)
set(CMAKE_CXX_STANDARD_REQUIRED True)
set(CMAKE_CXX_EXTENSIONS OFF)

set(OpenCV_DIR "/usr/local/opencv470")  # 根据实际安装路径修改
find_package(OpenCV REQUIRED)
include_directories(${OpenCV_INCLUDE_DIRS})
 
 
# 添加头文件搜索路径  
include_directories(include)
 
link_directories(/opt/halcon/lib/aarch64-linux)
 
aux_source_directory(. SRCS )
 
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS}  -static-libstdc++ -fPIC -Wl,--copy-dt-needed-entries -Wno-error=deprecated-declarations -Wno-deprecated-declarations ")
 
# 寻找./src下面所有.cpp为后缀的源文件,并且保存到SRC变量里面  
file(GLOB_RECURSE SRC ./src/*.cpp)  
  
# 编译SRC变量存储的源文件,编译生成目标文件命名为hello  
#add_executable(hello ${SRC})
add_library(hello SHARED src/HalconDemo.cpp)
target_link_libraries(hello halcon halconcpp hdevenginecpp)
target_link_libraries(hello ${OpenCV_LIBS}) 

python调用的程序为:

python 复制代码
import cv2
import numpy as np
from ctypes import cdll, c_char_p, c_int, POINTER
from ctypes import c_char
import ctypes
# 加载C库
imageprocessorlib = cdll.LoadLibrary('/libhello.so')


# 设置C函数的参数类型
imageprocessorlib.processimage.argtypes = [POINTER(c_char), c_int, c_int, c_int, ctypes.POINTER(ctypes.POINTER(ctypes.c_ubyte)), POINTER(c_int)]
# 设置C函数的返回类型
imageprocessorlib.processimage.restype = None

imageprocessorlib.free_memory.argtypes = [ctypes.POINTER(ctypes.c_ubyte)]
imageprocessorlib.free_memory.restype = None



def processimage(inputimage):
    height, width, channels = inputimage.shape
    inputdata = inputimage.ctypes.data_as(POINTER(c_char))
    
    # # 输出数据指针和大小
    # outputdata = POINTER(c_char)()
    # outputsize = c_int(0)

    output_data = ctypes.POINTER(ctypes.c_ubyte)()
    output_size = ctypes.c_int()
    
    # 调用C函数处理图像
    imageprocessorlib.processimage(inputdata, height, width, channels, output_data, output_size)



    if output_data and output_size.value > 0:
        # 将字节数组转换为NumPy数组
        image_array = np.ctypeslib.as_array((ctypes.c_ubyte * output_size.value).from_address(ctypes.addressof(output_data.contents)), shape=(output_size.value,))
        # 假设图像是灰度的,根据实际处理调整形状
        # height, width = 2048, 3072  # 你需要根据实际图像尺寸来设置这些值
        image = image_array.reshape((height, width))
        cv2.imwrite(r'/draw_ori_testopencv.bmp',image)

        # 释放C代码分配的内存
        imageprocessorlib.free_memory(output_data)
        return image
    else:
        return None
    
   

# 使用函数
if __name__ == '__main__':
    # 读取图像
    inputimage = cv2.imread('/images/9.bmp')
    
    # 处理图像
    processedimage = processimage(inputimage)
    
    # if processedimage is not None:
    #     # 显示图像
    #     cv2.imshow('Processed Image', processedimage)
    #     cv2.waitKey(0)
    #     cv2.destroyAllWindows()
相关推荐
weixin_156241575765 分钟前
基于YOLOv8深度学习花卉识别系统摄像头实时图片文件夹多图片等另有其他的识别系统可二开
大数据·人工智能·python·深度学习·yolo
AI_Claude_code10 分钟前
ZLibrary访问困境方案三:Web代理与轻量级转发服务的搭建与优化
爬虫·python·web安全·搜索引擎·网络安全·web3·httpx
小陈工12 分钟前
2026年4月7日技术资讯洞察:下一代数据库融合、AI基础设施竞赛与异步编程实战
开发语言·前端·数据库·人工智能·python
时空无限18 分钟前
ansible 由于不同主机 python 版本不同执行报错
python·ansible
会编程的土豆21 分钟前
【数据结构与算法】再次全面了解LCS底层
开发语言·数据结构·c++·算法
ZhengEnCi22 分钟前
P2E-Python字典操作完全指南-从增删改查到遍历嵌套的Python编程利器
python
alanesnape23 分钟前
使用AVL平衡树和列表实现 map容器 -- 附加测试/python代码
python·map·avl 平衡树·bst树·二叉树旋转
低频电磁之道25 分钟前
解决 Windows C++ DLL 导出类不可见的编译错误
c++·windows
卤炖阑尾炎43 分钟前
Python 网络编程实战:从 TCP/UDP 基础到高并发服务器开发
网络·python·tcp/ip
weixin_513449961 小时前
walk_these_ways项目学习记录第八篇(通过行为多样性 (MoB) 实现地形泛化)--策略网络
开发语言·人工智能·python·学习