python 与python通信、python调用c++ 动态库返回检测结果

python调用c++动态库 python调用动态库 阅读详情

项目需求

python 客户端将opencv读取到的图片发送给python服务端,然后python服务端将opencv图发送给Linux设备,将处理结果通过C++ 传给服务端,然后服务端再传给客户端。
这里服务端可以改成C++ 写的,就不用这么麻烦了,但是需要将python的pickle包解码成C++ 的pickle包,还未尝试。
以下所给代码,并不一定能跑通,思路在哪里,结合自己的代码

第一步,python间通信

这种方式能一次性全部发送,一次性全部接受(如发一张图片,接受一张,发两张,接受两张)

方法一

Python Client
import datetime
import pickle
import time
import cv2
from multiprocessing.connection import Client
import os

host = 'localhost'
port = 9006
frame_num = 0

def connect_and_send(path, mode='file'):
    global frame_num
    client = Client((host, port))
    while 1:
        img_dict_list = []
        # 从文件夹读取图片
        if mode == 'file':
            img_list = []
            img_path = './data'
            for filename in os.listdir(img_path):
                read_img = cv2.imread(img_path + '/' + filename)
                img_list.append(read_img)
            # 存入dict
            for i in range(len(img_list)):
                img_obj = {'frame_num': i + 1, 'image': img_list[i],
                           'time': time.strftime('%Y%m%d%H%M%S', time.localtime())}
                img_dict_list.append(img_obj)
        else:
            read_img = cv2.imread(path)
            img_obj = {'frame_num': frame_num + 1, 'image': read_img,
                       'time': datetime.datetime.now().strftime('%M%S.%f')}
            img_dict_list.append(img_obj)
            frame_num += 1

        # 1. obj to pickle 用json的话会慢,因为read_img需要to_list()
        data_bytes = pickle.dumps(img_dict_list)
        # 2. 发送文件
        print('client send: ', datetime.datetime.now().strftime('%M%S.%f'))
        client.send(data_bytes)

        det_result = client.recv()
        print('client receive: ', datetime.datetime.now().strftime('%M%S.%f'))
        det_result = pickle.loads(det_result)
        print(det_result)
        break


if __name__ == '__main__':
    connect_and_send('data/ship.jpg', mode='1')
Python Server端
import datetime
import pickle

import cv2
import numpy as np
from multiprocessing.connection import Listener

host = '192.168.0.2'
port = 9006
server_sock = Listener((host, port))
print("Connecting... ...")
sock = server_sock.accept()
while 1:
    try:
        received_bytes = sock.recv()
        print('server receive: ', datetime.datetime.now().strftime('%M%S.%f'))
    except Exception as e:
        received_bytes = None
        print(e)
    if not received_bytes:   # 当客户端下线,不让服务端下线
        server_sock.close()
        sock.close()
        print("Client's data is empty !!!")
        server_sock = Listener((host, port))
        print("Reset Sever")
        sock = server_sock.accept()
        continue
    else:
        # bytes to list
        img_dict_list = pickle.loads(received_bytes)
        # detect
        det_dict_list = []
        img_num = len(img_dict_list)

        img = img_dict_list[0]['image']
        # img send to server
        det_obj = {'frame_num': 1, 'det_output': getCResult(lib, det, img, img_num),  # getCResult获取检测结果
                   'time': datetime.datetime.now().strftime('%Y%m%d%H%M%S.%f')}
        det_dict_list.append(det_obj)
        # send result to client
        content = pickle.dumps(det_dict_list)
        print('server send: ', datetime.datetime.now().strftime('%M%S.%f'))
        sock.send(content)

参考链接:Python,用简单代码上传内存中的图片到远程服务器进行处理、Python传输图片(同一局域网下版本)

第二步,python调用C++ 动态库(opencv)返回检测结果

一共有cython、pybind11、ctypes等包,这里用的是ctypes
首先你需要有个.so文件,可以用cmake生成,注意python中你要调的包的位置,用camke不改.so文件的路径的话自动在当前文件夹生成,所以会报 **undefined symbol: strTest,**Linux指令:cp 复制文件
cmake自行查阅吧,这里做个示范

project(xxx)
add_library(xxx SHARED xxx.cpp)   //这里会将.cpp中的非类方法加入到.so文件中
add_executable(yyy yyy.cpp)
target_link_libraries(yyy xxx)
link:https://www.cnblogs.com/blog-3123958139/p/5575360.html

难点一:传输字符串 string to std::string

C++ 端:

extern "C" {   // 加了才能识别到括号内的方法,必须!用C格式写代码
	int Detect_Init(Detect* det, char* config_path){  // det用于调用类方法,后续会讲
    	std:string config_path1(config_path, sizeof(config_path));  // 将char*转为string类型
    	return det->Init(config_path1);
	}
}

python端

from ctypes import *
import ctypes

ll = ctypes.cdll.LoadLibrary
lib = ll("../lib/libDetect.so")
# 设置传递参数类型argtypes和返回类型restype
lib.Detect_new.argtypes = []
lib.Detect_new.restype = ctypes.c_void_p
lib.Detect_Init.argtypes = [ctypes.c_void_p, ctypes.c_char_p, ctypes.c_int]
lib.Detect_Init.restype = ctypes.c_int
# 创建一个Detect对象,后续会讲
det = lib.Detect_new()

# init
# 注意将string.encode()不行,编码到.就结束了
config = bytes("../../weights/DetectConfig.yaml", encoding='utf-8')  # 字符串任意,注意路径
# 如果需要传递可修改字符串,参考:https://zhuanlan.zhihu.com/p/215790047
# 使用create_string_buffer("test".encode('utf-8')) 
lib.Detect_Init(det, config)

参考链接:Python调用C的基础学习(传递数字、字符串、数组(一维、二维)、结构体)

难点二:调用C++ 类方法

C++ 端

class Foo{  //此处不贴自己的代码了,粘贴参考链接的代码
    public:
        Foo(int);
        void bar();
        int foobar(int);
    private:
        int val;
};
Foo::Foo(int n)  {val = nl;}
void Foo::bar() {
    std::cout << "Value is " << val << std::endl;
}
int Foo::foobar(int n)   {return val + n;}
extern "C"{  //用于python调用
    Foo* Foo_new(int n) {return new Foo(n);}  //核心点,创建一个调用类方法的对象
    void Foo_bar(Foo* foo) {foo->bar();}
    int Foo_foobar(Foo* foo, int n) {return foo->foobar(n);}
}

python端

import ctypes
lib = ctypes.cdll.LoadLibrary('./libfoo.so')   # 注意路径
class Foo(object):   # 也可以不写类,直接放在一个def里
    def __init__(self, val):
        lib.Foo_new.argtypes = [ctypes.c_int]
        lib.Foo_new.restype = ctypes.c_void_p
        lib.Foo_bar.argtypes = [ctypes.c_void_p]
        lib.Foo_bar.restype = ctypes.c_void_p
        lib.Foo_foobar.argtypes = [ctypes.c_void_p, ctypes.c_int]
        lib.Foo_foobar.restype = ctypes.c_int
        self.obj = lib.Foo_new(val)
    def bar(self):
        lib.Foo_bar(self.obj)
    
    def foobar(self, val):
        return lib.Foo_foobar(self.obj, val)

f=Foo(5)
# Calling f.bar() will print a message including the value...
f.bar()
# Now we'll use foobar to add a value to that stored in our Foo object, f
print (f.foobar(7))
# Now we'll do the same thing - but this time demonstrate that it's a normal
# Python integer...
x = f.foobar(2)
print (type(x))

参考链接:Calling C++ Classes from Python, with ctypes…、python 调用 C++ dll, 包含类以及opencv Mat、

难点三:传输结构体并带Mat图片

此处一个坑点是C++ 结构体的变量顺序和变量类型必须与python的类一致!!!!一定要仔细校对
C++ 类型和Python类型对照网址
二维数据在python里需要倒着写 C++ [20][5],python [5][20]
C++ 端

extern "C" {
 typedef struct 
{
    int image_num;
    int width[32];
    int height[32];
    char* frame[32];    // 注意是char* 网上不是uchar*就是POINTER(ubyte) 实际上char*也可,为了与python对应
}PythonImage;

void getInfo(PythonImage  input){  //验证是否传输成功
    printf("-----Information------\n");
    printf("width: %d, height: %d\n", input.width[0], input.height[0]);
}
DetectOutput Detect_Run(Detect* det, PythonImage  img){  // DetectOutput是嵌套结构体,只要细心一般都能返回
    cv::Mat frame(img.height[0], img.width[0], CV_8UC3, img.frame[0]);  // 将char* 转为 Mat格式
    return det->Run(frame);  //将图片发给检测算法
}
}

python端

from ctypes import *
import ctypes

class PythonImage(Structure):
    _fields_ = [('image_num', c_int),  # 注意 _fields_ 是双下划线
                ('width', c_int * val),  # val=32
                ('height', c_int * val),
                ('frame', c_char_p * val)]   # 与C++ 保持一致
        
ll = ctypes.cdll.LoadLibrary
lib = ll("../lib/libDetect.so")
lib.Detect_Run.argtypes = [ctypes.c_void_p, PythonImage]  # 注意此处填class名而不是Structure
lib.Detect_Run.restype = DetectOutput
det = lib.Detect_new()
pi = PythonImage()

PARAM = c_int * 32
height = PARAM()
height[0] = frame.shape[0]
pi.height = height

width = PARAM()
width[0] = frame.shape[1]
pi.width = width
# 对cv2图片进行处理
frame_data = np.asarray(frame, dtype=np.uint8)
frame_data = frame_data.ctypes.data_as(c_char_p)
pi.frame[0] = frame_data
pi.image_num = image_num  # 传输图片的数量

lib.getInfo.argtypes = [PythonImage]
lib.getInfo(pi)
lib.Detect_Run(det, pi)  # 检测结果

参考链接:python调用c/C++ 时传递结构体参数

小难点1:嵌套结构体传输/读取指针值/ctypes BUG?

注意C++ 结构体的变量顺序和变量类型必须与python的类一致!!!!一定要仔细校对,其他应该没有什么问题
C++ 端

typedef enum AttributeType
{
    PERSON_HEAD = 0,                          
    PERSON_NECK,             
} AttributeType;

typedef struct cv_box 
{
    float x;                              
    float y;                             
    float w;                                            
    float h;                                              
} cv_box;                                              
   
typedef struct cv_object
{
    cv_box bbox;                             
    int classes;                                                           
    float *prob;                                 
    AttributeType attribute;       
    int a[7];
} cv_object;    

typedef struct cv_object_list
{
    cv_object object[128];
    int object_num;   // 注意这里的顺序 必须object_num 在object[128] 上面,  !!!bug
										// 即两行互换位置,否则无法读取object_num的值,具体为什么不清楚
	int test[7];
}cv_object_list; 

python端

class cv_box(Structure):
    _fields_ = [('x', c_float),
                ('y', c_float),
                ('w', c_float),
                ('h', c_float)]

class cv_object(Structure):
    _fields_ = [('bbox', cv_box),
                ('classes', c_int),
                ('prob', POINTER(c_float)),  
                ('attribute', c_int),   # 枚举类型是c_int
                ('a', c_int * 7)]

class cv_object_list(Structure):
    _fields_ = [('object', cv_object * 128),
                ('object_num', c_int),
               ('test', c_int * 7)]
# 输出指针值
prob = POINTER(c_float)(object[0].prob)   # 即float* prob
print(prob.contents.value)  # 获取到c_float()中括号内的值
参考链接:https://blog.csdn.net/Kelvin_Yan/article/details/86546784#t2

小难点2:python获取C++ .h文件内容

参考链接:Python解析C++ 头文件

import CppHeaderParser

cppHeader = CppHeaderParser.CppHeader("../include/type.h")
val = 32
OBJECT_NUM = 128
for h in cppHeader.defines:
    if 'BATCH_SIZE' in h:
        val = int(h.split(' ')[-1])
    if 'OBJECT_NUM' in h:
        OBJECT_NUM = int(h.split(' ')[-1])

第三步 传输视频

参考博客:opencv cv2.imshow显示图片一片黑色、 python:读取视频,处理后,实时计算帧数fps、opencv imencode跟imdecode函数jpg(python)
首先如果转换m4s格式到mp4格式,使用命令:ffmpeg -i all.m4s -c copy video.mp4
这个比较简单,总体思路就是opencv读取视频,按帧发送,然后接受回传结果并绘制
客户端

def send_data(img_dict):
    start = int(round(time.time() * 1000))
    start_time = time.strftime("%Y-%m-%d %H:%M:%S", time.localtime())
    # 1. send data
    data_bytes = pickle.dumps(img_dict)
    client.send(data_bytes)  # 貌似client是全局变量
    # 2. receive data
    det_result = client.recv()
    det_result = pickle.loads(det_result)
    # print(det_result)
    # cal time cost
    end = int(round(time.time() * 1000))
    end_time = time.strftime("%Y-%m-%d %H:%M:%S", time.localtime())
    time_cost = end - start
    print('client total time cost: ', time_cost)
    # 3. draw boxes 自己写
    draw_box(det_result, img_dict)
    # 4. save logs 自己写
    det_frame_num = det_result['frame_num']
    save_logs(time_cost, start_time, end_time, det_frame_num)

def image_send(img):
    global frame_num
    img_param = [cv2.IMWRITE_JPEG_QUALITY, 95] # 压缩率
    _, img = cv2.imencode('.jpg', img, img_param)
    # 为了统一图片,如果单要视频,可以直接传输图片img
    img_obj = {'frame_num': frame_num, 'image': img}
    frame_num += 1
    send_data(img_obj)

def read_video_send(path):
    global frame_num
    frame_num = 1  # 重置frame_num 使其适配视频第一帧
    video = cv2.VideoCapture(path)
    while True:
        _, img = video.read()
        cv2.imshow('client', img)
        cv2.waitKey(1)  # 不加就黑屏
        start = time.time()
        image_send(img)  # send img
        end = time.time()
        seconds = end - start
        fps = 1 / seconds
        print("Estimated FPS: {0}".format(fps))	
        
if __name__ == '__main__':
    img_file = './data'
    img_pa = './data/1.jpg'
    client = Client((host, port))
    mode = 'video'
    if mode == 'image':
        read_img = cv2.imread(img_pa)
        image_send(read_img)
    elif mode == 'images':
        read_images_send(img_file)
    elif mode == 'video':
        read_video_send('./video/1.mp4')

服务端

def connect_send(host, port, lib, det):
    server_sock = Listener((host, port))
    print("Connecting... ...")
    sock = server_sock.accept()
    while 1:
        try:
            received_bytes = sock.recv()
        except Exception as e:
            received_bytes = None
            print(e)
        if received_bytes is None:  # 不能是not received,否则传视频有问题
            server_sock.close()
            sock.close()
            print("Client's data is empty !!!")
            server_sock = Listener((host, port))
            print("Reset Sever")
            sock = server_sock.accept()
            continue
        else:
            # bytes to list to cv
            img_dict = pickle.loads(received_bytes)
            img_dict['image'] = cv2.imdecode(img_dict['image'], cv2.IMREAD_COLOR)
            # detect one image
            det_dict = detect_img(img_dict, lib, det, 1)
            # send result to client
            content = pickle.dumps(det_dict)
            sock.send(content)
python-调用动态链接库dll/so的方法 使用python ctyeps CDLL来调用linux下的so动态链接库或windows下的dll动态链接库 阅读详情

相关推荐

C++集成ZXing-cpp与OpenCV实现高性能二维码识别

二维码识别是计算机视觉中的一项基础技术,其核心原理是通过图像处理算法定位和解码二维矩阵中的编码信息。ZXing作为广泛使用的开源条码库,以其对多种码制的全面支持和算法鲁棒性而著称。在C++高性能项目中,直接集成其C++端口zxing-cpp,可以避免跨语言调用的开销,实现毫秒级延迟的实时处理。通过封装一层简洁的OpenCV接口,开发者能将cv::Mat图像数据无缝转换为ZXing内部格式,并利用其强大的解码能力处理QR Code、Data Matrix等多种格式。这种结合特别适用于嵌入式视觉、工业检测等对性

weixin_30522183的博客 401

Python调用C/C++动态链接库

Python调用C库的方法

牧羊女 6404

Lua调用C++函数:原理、实现与工程实践指南

在软件架构设计中,脚本语言与高性能编译语言的混合编程是一种常见模式,旨在兼顾开发效率与执行性能。其核心原理在于通过特定的应用程序接口(API)和虚拟栈机制,实现两种语言环境间的数据交换与函数调用。这项技术的核心价值在于,它允许开发者将计算密集、底层硬件操作等高性能需求模块用C/C++实现,同时将易变、配置化的业务逻辑交由Lua等脚本处理,从而达成架构解耦与灵活部署。典型的应用场景包括游戏开发中的逻辑与引擎分离、嵌入式系统中的应用层脚本化,以及为大型C++程序提供插件扩展能力。本文将以Lua调用C++函数这一

weixin_30740295的博客 345

Python脚本调用C++动态库,C++调用Python脚本实操

注:虽然按照上述步骤操作了,但是很多时候运行脚本会报“找不到XXX模块的错”,这个时候就需要注意你当前调用的dll是否依赖了别的库,如果有需要把依赖的库一起拷到同一文件夹。把生成的动态库和脚本放在同一文件夹,然后执行脚本,就可以调用C++动态库里的函数了。直接引入python.h文件肯定会报错的,需要设置相关属性,打开工程属性,做如下设置。还是使用之前的脚本,内容如下,命令robotFlow.py。的错,解决方法是在object.h文件下添加如下代码。然后执行程序,整个流程就结束了。

wu_xiang_chao的博客 2398

C++与Python跨语言调用性能优化:从300ms到3ms的实战指南

在异构系统开发中,跨语言调用是连接不同技术栈的关键桥梁,其性能直接影响系统整体效率。其核心原理涉及数据序列化、内存管理和执行上下文切换等底层机制。通过优化这些环节,可以显著提升技术价值,实现高性能计算与快速迭代的平衡。在人工智能、科学计算和高频交易等应用场景中,高效的跨语言通信尤为重要。本文聚焦于C++与Python互调场景,深入探讨如何通过零拷贝技术和GIL优化等策略,解决序列化开销和数据拷贝等性能瓶颈,实现百倍性能提升。

weixin_30565327的博客 431

C++动态库封装远程数据库访问:ODBC连接池与跨平台实践

动态链接库(DLL/SO)是C++实现模块化、代码复用和系统解耦的核心技术,它通过将功能封装为独立的二进制模块,实现运行时加载与资源共享。其原理在于导出标准接口,使主程序与库实现分离,从而提升系统的可维护性和部署灵活性。在数据库访问场景中,这一技术价值尤为凸显,它能将复杂的网络通信、连接管理与SQL执行逻辑封装起来,为上层应用提供稳定高效的API。通过设计合理的连接池,可以管理数据库连接生命周期,有效应对高并发请求,避免频繁建立与断开连接的开销。本文以ODBC为底层接口,结合连接池管理与跨平台编译,详细阐述

404

windows环境下python调用cpp动态库(win10+opencv)

【前言】在windows环境下,可以利用python直接调用cpp的动态链接库,从而达到混合编程的目的。 一、cpp的动态链接库 windows下编译cpp的动态链接库的技术比较多了,这里指出两处需要特别注意的地方: (1)要利用extern "C"关键字,实现C编译; (2)pythoe与 cpp的接口最好重写,即在功能函数外面添加一层包装,在包装内实现数据交换。 二、python调用cpp的动态链接库 主要注意三个地方: (1)dll如果依赖于其他动态库(如opencv),则必须保证其他被

sunzhao1000的博客 2710

C++项目集成Python/Lua脚本:原理、选型与Sol2/pybind11实战

在软件工程中,脚本语言集成是一种常见的设计模式,旨在平衡系统性能与开发灵活性。其核心原理是通过虚拟栈和类型映射机制,在静态编译语言(如C++)与动态解释语言(如Python、Lua)之间建立通信桥梁,实现双向函数调用与数据交换。这项技术的核心价值在于提升项目的可扩展性和开发迭代效率,允许将易变的业务逻辑、游戏规则或配置参数交由脚本处理,支持热更新而无需重新编译主程序。在应用场景上,它广泛用于游戏开发(如角色行为逻辑)、工具链插件系统、以及需要快速迭代的业务规则引擎。本文以C++项目为背景,深入探讨了如何通过

weixin_34414196的博客 281

Windows中Boost:python简单示例—— python调用c++函数

一、啰嗦的背景介绍 最近在做的项目,小伙伴们主体功能想使用python。而通信模块,老师要求我使用成熟的C++框架,因为通信模块需要与对方的c++服务器进行连接。最开始有同学研究了一下python如何调用c++,也给自己发了链接: 如何实现 C/C++ 与 Python 的通信? 浅谈Python C扩展 自己看了一会,就觉得过程太复杂。灵机一动,自己目前使用Boost.Asio进行网络通...

lucyLee的博客 4165

Python与C++在老旧小区改造数字化中的实践:500个APP案例解析

在数字化转型浪潮中,老旧小区改造项目面临着信息滞后、管理复杂等挑战。通过引入Python和C++技术栈,可以实现从数据整合、流程自动化到物联网集成的全面升级。Python凭借其丰富的生态库,如pandas、Django和OpenCV,在数据处理、Web后端和图像识别等场景中发挥关键作用;而C++则以其高性能特性,在物联网关、实时图形渲染和边缘计算等对性能要求极高的领域成为核心。这种技术组合不仅提升了工程管理的效率,还通过智慧社区建设改善了居民服务体验。本文通过具体案例,深入探讨了如何利用这两门经典语言解决老

weixin_33782386的博客 305

C#调用llama.cpp运行PaddleOCR-VL-1.5实现本地文档理解

文档理解(Document Understanding)是OCR技术从‘识别文字’迈向‘解析语义’的关键演进,其核心在于融合视觉定位与语言推理能力。基于视觉-语言联合理解(VL)原理,PaddleOCR-VL-1.5通过三段式架构(量化ViT编码器+指令微调语言头+跨模态对齐层),在边缘设备上原生输出结构化JSON与检测框坐标,显著提升字段抽取精度与空间可解释性。该技术具备低延迟、离线运行、零云依赖等工业级部署价值,广泛适用于金融票据自动填单、医疗报告关键指标抽取、合同风险条款高亮等强合规、高实时性场景。本

weixin_30607029的博客 511

python什么模块动态调用链接库_windows环境下python调用cpp动态库

第一部分、前言在windows环境下,可以利用python直接调用cpp的动态链接库,从而达到混合编程的目的。一、cpp的动态链接库windows下编译cpp的动态链接库的技术比较多了,这里指出两处需要特别注意的地方:(1)要利用extern "C"关键字,实现C编译;(2)pythoe与 cpp的接口最好重写封装,即在功能函数外面添加一层包装,在包装内实现数据交互。二、python调用cpp的动...

weixin_39942474的博客 185

工业软件C++与Python融合架构实战:从设计到部署的完整指南

在工业软件与高性能计算领域,跨语言混合编程是解决性能与开发效率矛盾的关键技术。其核心原理在于利用不同编程语言的特长进行分工协作,例如C++负责底层高性能计算和实时控制,Python则专注于上层业务逻辑与快速原型开发。这种架构的技术价值在于,它能将C++的执行效率、系统级控制能力与Python的快速开发、丰富生态完美结合,从而构建出既稳定可靠又灵活易用的软件系统。在实际应用中,该技术广泛服务于工业自动化、CAD/CAE、机器视觉和物联网等场景,通过诸如pybind11等绑定工具实现无缝集成。本文以工业软件为背

ciya3282的博客 361

llm.cpp:面向本地大模型部署的C++底层推理运行时

大语言模型本地部署的核心挑战在于确定性、可控性与跨环境一致性。C++凭借零抽象内存布局、ABI稳定性与实时性保障,成为构建高可靠推理运行时的首选语言;GGUF作为自描述二进制模型格式,实现了‘模型即文件’的交付范式,天然支持跨框架加载与量化固化;而CUDA的精细化控制(如架构精准匹配、GPU层粒度分片)则直接决定了性能边界的可预测性。本文聚焦llm.cpp这一轻量级C++运行时,解析其如何通过剥离UI/网络/自动调度等高层抽象,为开发者提供对GGUF模型加载、CUDA kernel调度与显存分配的全程可观测

417

Python调用动态链接库(DLL)

上述Python代码中,使用ctypes.CDLL方法加载sum.dll文件,并指定其路径。动态链接库(Dynamic Link Libraries,简称DLL)是一种被多个程序共享的库文件,可以被用于将程序分解为小模块,减少内存占用,加快程序运行速度。但需要注意的是,在使用ctypes库时,需要确保本机的硬件和操作系统与目标DLL文件的硬件和操作系统匹配。编译上述代码并生成dll文件,例如生成名为sum.dll的文件。最后,调用sum_dll.sum(1, 2)可以得到1和2的和,输出结果为3。

2301_78484069的博客 4663

C++跨进程调用Python全栈实战 | 三管道匿名IPC+JSON标准化交互,助力机器视觉YOLO训练、图像推理、工业检测高效解耦落地

在工业机器视觉、深度学习自动化项目开发中,长期存在技术栈割裂、工程落地矛盾突出的行业痛点。Python凭借Ultralytics、PyTorch、OpenCV、NumPy等丰富开源生态,成为深度学习模型训练、图像特征推理、智能算法迭代的首选语言,开发效率高、算法适配性强;而C++具备高性能、低延迟、内存可控、稳定性极强的优势,是工业上位机、PLC硬件交互、实时流水线调度、7×24小时量产设备主控的核心开发语言。

getusushu的博客 11

[已解决] Python调用C++ Dll打包运行时报错: Failed to load dynlib/dll xxx.dll

Python通过ctypes调用C++ Dll库,pyinstaller打包成exe后在本机正常运行,但是放到别的PC上单独运行就报错,提示: > PyInstallerImportError: Failed to load dynlib/dll xxxx.dll ... **注:我这里是将该dll打包进了exe,但尝试把dll文件直接放入exe目录中 也同样报错** 报错信息如下图:

HowieXue 薛永浩的博客 1万+

看完这篇爽文我终于学会了示波器(一)

示波器基础篇的介绍,希望对你有用,下次分享一下如何测试。

qq_45508321的博客 972

C++实现QQ域名封禁检测工具:原理、开发与优化指南

在网络应用开发与运维中,自动化监控是保障服务可用性的关键技术。其核心原理在于通过程序模拟客户端请求,获取并解析服务器响应,从而实现对目标状态的实时感知。这种技术对于链接推广、社群运营及机器人开发等领域具有重要价值,能有效避免因域名被封禁导致的流量损失。本文聚焦于QQ生态下的特定应用场景,详细阐述了如何利用C++的高效特性与cURL库的网络能力,构建一个稳定可靠的域名封禁状态检测工具。通过模拟QQ客户端的请求过程,该工具能够自动化、批量化地完成检测任务,并支持集成到后台服务中实现7x24小时不间断监控,为开发

weixin_30407613的博客 396

STM32 HAL库 实现基于SPI模式的SD卡、TF卡FATS文件系统+模拟U盘的应用笔记

很多单片机不带SDIO接口,所以在使用SD卡时必须使用SPI模式进行读写。 想做一个基于SPI的SD卡文件系统读写SD卡上的文件,再配合USB接口做一个模拟U盘。只能利用业余时间慢慢更新,也不知道能不能坚持下去。 我会把从零开始开发一个程序需要经历的过程一一的记录下来。做成一个奶妈级的单片机开发笔记。 一、硬件简介 1.SD卡和MicroSD卡(TF卡)的区别 由下图可以很容易的看出TF卡只是比SD卡少了一个3脚Vss脚,其它的管脚顺序

KyleKuang的博客 8331

STM32驱动数码管:从硬件连接到动态显示实现

本文详细介绍了使用STM32单片机驱动数码管的完整流程,从硬件连接到软件实现。内容涵盖共阳/共阴数码管原理、GPIO配置、段码表生成,并重点解析了多位数码管动态显示的核心技术,包括动态扫描原理、消影处理及实战代码,帮助开发者快速掌握这一嵌入式开发基础技能。

p5l2m9n4o6q的博客 574
上一篇: 域名购买+博客搭建
下一篇: 混合编程之多线程
AlexNett
博客等级 码龄9年 562粉丝 40原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

当前余额3.43元 前往充值 >
需支付:10.00元
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付元
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值