[C Language] Linux Callback+ShareMemory方式

本文探讨了在多方合作开发场景下,通过Callback函数与共享内存的结合使用,实现跨进程数据交换的有效策略。详细介绍了如何在底层实现A中设置共享内存及回调函数,以及应用层B如何注册并响应这些回调,确保数据的正确读取与处理。


1.Callback函数与共享内存方式结合:符合第三方黑盒子调用。

2. 适应与多方合作开发。

//test_callback.h

#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <pthread.h>
#include <sys/shm.h>
#include "shmdata.h"
#include <cstring>

using namespace std;
//-----------------------底层实现A-----------------------------
typedef void (*pcb)(char *s); //函数指针定义,后面可以直接使用pcb,方便

typedef struct parameter{
    char text[2048];//记录写入和读取的文本
    pcb callback;
}parameter;
 

 

//留给应用层B的接口函数
void init();
bool read();
void* callback_thread(void *p1);
extern void SetCallBackFun(const char *s, pcb callback);

//test_callback.cpp

#include "test_acallback.h"

#define SHARE_ID 1234

struct shared_use_st *shared;//指向shm

void init()
{
 void *shm = NULL;//分配的共享内存的原始首地址
 int shmid;//共享内存标识符
    //创建共享内存
 shmid = shmget((key_t)SHARE_ID, sizeof(struct shared_use_st), 0666|IPC_CREAT);
  
 if(shmid == -1)
 {
  fprintf(stderr, "shmget failed\n");
  exit(EXIT_FAILURE);
 }

 shm = shmat(shmid, 0, 0);

 if(shm == (void*)-1)
 {
  fprintf(stderr, "shmat failed\n");
  exit(EXIT_FAILURE);
 }
 printf("\nMemory attached at %X\n", (long)shm);

 //设置共享内存
 shared = (struct shared_use_st*)shm;
}

bool read()
{
 bool ret = false;
    if(shared->written != 0)
 {
        printf("You wrote: %s", shared->text);
     sleep(rand() % 3);
     //读取完数据,设置written使共享内存段可写
           shared->written = 0;
     return true;
 }else
 {
  return false;
 }
}

void* callback_thread(void *p1)//此处用的是一个线程
{
    //do something
    parameter* p = (parameter*)p1 ;
 init();
    while(1)
    {
        //printf("GetCallBack print! \n");
  if(true == read())
  {
   
   sprintf(p->text,"%s",shared->text);
   printf("GetCallBack print=%s\n\n",p->text);
   p->callback(p->text);//函数指针执行函数,这个函数来自于应用层B
  }  
  else
     {
   sleep(1);
   continue;
  }
        sleep(1);//延时3秒执行callback函数
     
    }
}

extern void SetCallBackFun(const char *s, pcb callback)
{
    printf("SetCallBackFun print! \n");
    parameter *p = (parameter*)malloc(sizeof(parameter)) ;
    sprintf(p->text,"%s",s);
    p->callback = callback;

    //创建线程
    pthread_t thing1;
    pthread_create(&thing1,NULL,callback_thread,(void *) p);
    pthread_join(thing1,NULL);
}

//test_bcallback.cpp

#include <stdio.h>
#include <cstring> 
#include "test_acallback.h"

using namespace std;
//-----------------------应用者B-------------------------------
void fCallBack( char *s)       // 应用者增加的函数,此函数会在A中被执行
{
    //do something
    printf("tty_best = %s\n",s);
    printf("fCallBack print!\n");
}


int main(void)
{
    SetCallBackFun("start",fCallBack);
    return 0;
}

<think>好的,我需要解决用户关于libusb1.0.so库中libusb_hotplug_deregister_callback函数的问题。用户提到文档或错误在偏移量+84处,可能遇到了运行时错误或崩溃。首先,我需要回忆libusb的相关文档。 我记得libusb_hotplug_deregister_callback函数用于注销之前注册的热插拔回调。函数原型应该是void libusb_hotplug_deregister_callback(libusb_context *ctx, libusb_hotplug_callback_handle handle)。用户可能在调用时传入了错误的句柄或上下文,导致错误。偏移量+84可能是指反汇编或错误信息中的位置,可能与库版本或符号不匹配有关。 接下来,检查常见错误原因。比如,是否在注销后再次使用已释放的资源,或者多次注销同一个句柄。此外,库版本兼容性也很重要,比如libusb 1.0.22之后的热插拔API变化。用户可能需要确认库版本是否正确,并确保函数调用参数正确。 然后,考虑如何验证这些问题。建议用户检查回调注册和注销的调用顺序,使用valgrind检测内存错误,或者查看堆栈跟踪以确定崩溃位置。同时,查阅官方文档和社区资源,如libusb.info或GitHub issues,寻找类似问题的解决方案。 最后,生成相关问题,帮助用户进一步排查,比如如何正确使用热插拔回调,版本兼容性问题,以及调试方法等。</think>关于libusb_hotplug_deregister_callback函数的问题分析及解决方法如下: 1. **函数功能说明** `libusb_hotplug_deregister_callback`用于注销通过`libusb_hotplug_register_callback`注册的设备热插拔事件监听。其原型为: ```c void libusb_hotplug_deregister_callback(libusb_context* ctx, libusb_hotplug_callback_handle handle); ``` 需要传入有效的上下文指针和回调句柄[^1]。 2. **常见错误原因** - **非法句柄**:传入已注销或无效的`handle`参数 - **上下文不匹配**:使用不同`libusb_context`实例注册/注销 - **多线程竞争**:未正确同步导致重复注销 - **内存越界**:偏移量+84错误可能与栈损坏相关 3. **调试建议** ```bash # 使用addr2line定位偏移量 addr2line -e /usr/lib/x86_64-linux-gnu/libusb-1.0.so.0.3.0 0x84 ``` 4. **代码检查示例** ```c libusb_hotplug_callback_handle handle; // 注册回调 libusb_hotplug_register_callback(NULL, LIBUSB_HOTPLUG_EVENT_DEVICE_ARRIVED, 0, LIBUSB_HOTPLUG_MATCH_ANY, LIBUSB_HOTPLUG_MATCH_ANY, hotplug_callback, NULL, &handle); // 正确注销 libusb_hotplug_deregister_callback(NULL, handle); ```
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值