0
  • 聊天消息
  • 系统消息
  • 评论与回复
登录后你可以
  • 下载海量资料
  • 学习在线课程
  • 观看技术视频
  • 写文章/发帖/加入社区
会员中心
创作中心

完善资料让更多小伙伴认识你,还能领取20积分哦,立即完善>

3天内不再提示

通过RealSense代码说明一些C语言问题

云深之无迹 来源:云深之无迹 2023-04-26 10:20 次阅读

以前也读了这个RGBD相机的一些源码但是发现自己的基本功是一点也不好,所以就搁置了很久,今天试图来回答一些问题。

说好的不会再出新品结果还是出了,估计这个市场还是可以的

e63a0740-e351-11ed-ab56-dac502259ad0.png

自己就看一个例子里面的代码

e655f752-e351-11ed-ab56-dac502259ad0.png

就一个C文件,看的也简单一些

set(CMAKE_EXPORT_COMPILE_COMMANDS 1)


add_executable(rs-color rs-color.c ../example.h)
include_directories(../../common ../../third-party/imgui ../../C)
target_link_libraries(rs-color ${DEPENDENCIES})
set_target_properties (rs-color PROPERTIES
FOLDER "Examples/C"
)


install(TARGETS rs-color RUNTIME DESTINATION ${CMAKE_INSTALL_BINDIR})

编译的文件都是使用Cmake来控制的,所以一开始写一些这个。

set(CMAKE_EXPORT_COMPILE_COMMANDS 1) 这个命令会让CMake在编译过程中输出 JSON 格式的编译命令到 compile_commands.json 文件中。这对于IDE的代码补全和静态分析很有帮助。

add_executable(rs-color rs-color.c ../example.h) 这个命令定义了一个rs-color的可执行目标,源代码文件是rs-color.c和example.h。

include_directories(../../common ../../third-party/imgui ../../C) 这个命令指定了包含路径,用于解析rs-color.c和example.h中的#include语句。

target_link_libraries(rs-color ${DEPENDENCIES}) 这个命令为rs-color目标指定了链接库,其中${DEPENDENCIES}是一个变量,包含所有依赖库的名字。

set_target_properties (rs-color PROPERTIES FOLDER "Examples/C" )这个命令为rs-color目标设置了一些属性,这里指定了在IDE的项目视图中,rs-color会出现在Examples/C文件夹下。

e66d398a-e351-11ed-ab56-dac502259ad0.png

直接下来就看几个代码,是不是和学的C语言不太一样

这条语句rs2_error *e = 0;

1. 定义了一个指针e,指向rs2_error类型。

2. 将e初始化为0,也就是RS2_ERROR_NONE,表示没有错误。

rs2_context *ctx = rs2_create_context(RS2_API_VERSION, &e);

源码使用 Intel RealSense SDK 的 C API 创建了一个上下文对象 rs2_context,并将其地址赋给 ctx 变量。

同时,它传递了 RealSense SDK 的 API 版本号 RS2_API_VERSION 给 rs2_create_context() 函数,该函数将返回一个 rs2_context 对象。

在创建上下文对象时,还传递了一个错误处理器(error-handler)的地址 &e,以便在运行时捕获可能出现的错误。

如果发生someError,会通过*e = ...将e设置为相应的错误码。之后,在调用者可以检查*e的值来查看doSomething()是否发生错误。这是C语言中一个很常见的错误处理方式 - 通过指针传递错误码,如果有错误,被调用的函数会设置该指针为错误值。

e694cd4c-e351-11ed-ab56-dac502259ad0.png

调用者在调用后检查该值来进行错误处理。这种方式的好处是:

可以从函数返回额外的错误信息(除了函数返回值本身)。

不需要定义专门的错误返回类型,可以直接使用指向已有类型的指针。

简单和实用,适用于C语言的语法和习惯。

当然,这个方式也有一定的缺点,比如:

1. 如果不注意检查错误指针,难以发现错误,这会影响健壮性。

2. 错误指针需要与函数的正确返回值区分开来检查,有一定难度。

3. 错误信息只能通过指定的指针值返回,表达能力较有限。所以,对于rs2_error *e这样的指针,是可以直接作为C函数的参数进行传递的,这是C语言中一种简单实用的错误处理方式,但是也有一定的缺陷。

e6a709d0-e351-11ed-ab56-dac502259ad0.png

在这里被定义了很多

e6c802f2-e351-11ed-ab56-dac502259ad0.png

更具体的实现

1.析构函数~rs2_context(),在rs2_context被释放时会调用ctx->stop()。这是用于停止某个线程或后台服务。

2. 一个std::shared_ptr<:context>成员ctx。这是一个librealsense库中的context对象,通过shared_ptr智能指针进行管理。可以猜测,这个rs2_context结构体表示一个与librealsense的context相关的对象,它在释放时会停止该context,并通过shared_ptr管理context的生命周期。 其实这也是一个使用RAII(Resource Acquisition Is Initialization),通过在对象构造和析构时启动和停止资源,实现资源的自动管理。

  rs2_context *ctx = rs2_create_context(RS2_API_VERSION, &e);

这段代码中,通过调用rs2_create_context()函数创建了一个rs2_context 实例,并将该实例的指针赋值给了 ctx 变量。这个 rs2_context 实例是在 rs2_create_context() 函数内部创建并初始化的,然后将其地址返回给调用者,调用者通过 ctx 变量来访问和操作该实例。

可以说rs2_context实例已经被初始化并设置好了,但不能直接说 rs2_context 里面是一个已经初始化过的结构体,因为 rs2_context 只是一个指针类型,并不存储任何数据。

结构体指针在 C 语言中被广泛使用,因为它可以方便地访问和操作结构体中的成员,而不需要对整个结构体进行复制。结构体指针可以通过指针运算和取值运算符来访问结构体成员,这使得对结构体的操作变得更加高效。

以下是一些常见的使用结构体指针的场景:

传递结构体指针作为函数参数:这种情况下,函数可以通过指针来访问和修改结构体的成员,从而避免了对整个结构体进行复制,提高了程序的效率。

动态内存分配:当需要动态创建一个结构体对象时,需要使用结构体指针来指向该对象。在动态分配内存时,使用结构体指针可以确保只分配所需的内存,并且可以方便地释放分配的内存。

链表和树等数据结构:链表和树等数据结构通常使用结构体指针来连接不同的节点,从而构建出完整的数据结构。

 rs2_context *rs2_create_context(int api_version, rs2_error **error);

- api_version参数指定了librealsense API的版本号,用于向后兼容。
-e是个指针,如果有错误发生,会被设置为错误码。这是C语言常见的错误返回方式。

包含了以下字段:

message:错误消息,描述错误 details 的字符串。

function:发生错误的函数名。

args:发生错误的函数调用的参数。

exception_type:错误类型,很可能是一个enum,表示出错的原因。这个结构体通常用来表示异常信息,或是库函数调用后的错误详情。

c++
struct rs2_error 
{
    std::string message;   // 错误消息
    std::string function;  // 函数名
    std::string args;     // 函数参数
    rs2_exception_type exception_type; // 错误类型
};

如果一个函数返回一个结构体类型的值,那么需要使用一个结构体类型的变量来接收这个返回值。因为结构体类型通常比较大,如果直接将结构体类型的值作为函数的返回值返回,会导致复制整个结构体的内存空间,从而影响程序的性能。因此,C 语言中通常使用指向结构体的指针作为返回值,而不是直接返回结构体类型的值。

#include 
#include 


struct person {
    char name[50];
    int age;
};


struct person* create_person(const char* name, int age) {
    struct person* p = (struct person*) malloc(sizeof(struct person));
    if (p != NULL) {
        strcpy(p->name, name);
        p->age = age;
    }
    return p;
}


int main() {
    struct person* p = create_person("John Doe", 30);
    if (p != NULL) {
        printf("Name: %s
", p->name);
        printf("Age: %d
", p->age);
        free(p);
    }
    return 0;
}

完整代码

e6d9b45c-e351-11ed-ab56-dac502259ad0.png

看这个

在上面的例子中,create_person() 函数返回一个指向:

 struct person

结构体的指针。

该函数使用malloc()函数动态分配内存来存储结构体,然后将结构体的成员赋值为传入的参数。最后,该函数返回指向该结构体的指针。在 main() 函数中,调用 create_person() 函数来创建一个结构体实例,并打印出其成员的值。在使用完结构体后,还需要调用 free() 函数来释放动态分配的内存。

更具体的来分析:

    struct person* p = (struct person*) malloc(sizeof(struct person));

调用malloc()函数,请求分配sizeof(struct person)字节的内存块。这将分配足够存放person结构体的内存。

malloc()返回 void *,所以我们需要强制类型转换为struct person*。这会将void *转换为person结构体的指针。

person *p将保存分配的内存块地址,我们可以通过p访问这个person对象。

分配的内存未初始化,需要手工初始化 person 对象的各个字段。

使用malloc()获取内存,强制类型转换为需要的指针类型,使用后释放内存。

https://www.intelrealsense.com/
https://github.com/IntelRealSense/librealsens

审核编辑:汤梓红

声明:本文内容及配图由入驻作者撰写或者入驻合作网站授权转载。文章观点仅代表作者本人,不代表电子发烧友网立场。文章及其配图仅供工程师学习之用,如有内容侵权或者其他违规问题,请联系本站处理。 举报投诉
  • 相机
    +关注

    关注

    4

    文章

    1347

    浏览量

    53541
  • C语言
    +关注

    关注

    180

    文章

    7602

    浏览量

    136359
  • 命令
    +关注

    关注

    5

    文章

    679

    浏览量

    22000
  • 代码
    +关注

    关注

    30

    文章

    4762

    浏览量

    68408
  • RealSense
    +关注

    关注

    0

    文章

    11

    浏览量

    19356

原文标题:通过RealSense代码说明一些C语言问题

文章出处:【微信号:TT1827652464,微信公众号:云深之无迹】欢迎添加关注!文章转载请注明出处。

收藏 人收藏

    评论

    相关推荐

    分享一些超级炫酷的C语言小技巧

    C语言常常让人觉得它所能表达的东西非常有限。它不具有类似第级函数和模式匹配这样的高级功能。但是C非常简单,并且仍然有一些非常有用的语法技巧
    发表于 11-07 11:25 695次阅读

    试用 Intel RealSense

    Pro) 右上角。我们正在通过 PC 上的 RealSense 开发者工具运行一些样本数据。与常规网络摄像头不同,这款摄像头模块可以使用红外线测量距离。因此它可以识别人类的动作和手势,还能以 3D
    发表于 09-25 00:21

    Linux内核中GNU C扩展的一些常用C语言语法分析

    13.1 总结前面12节的课程,主要针对 Linux 内核中 GNU C 扩展的一些常用 C 语言语法进行了分析。GNU C 的这些扩展语法
    发表于 12-14 06:29

    C语言使用必须了解的一些问题495个C语言问题选集免费下载

    《你必须知道的495个C语言问题》书于2009年由人民邮电出版社出版发行,该书以问答的形式组织内容,讨论了学习或使用C语言的过程中经常遇到
    发表于 11-01 11:46 22次下载

    C语言C++编程的一些思考资料说明

    1、其实高级语言和面向过程的语言最求的目标都是致的,高可复用性,另外,封装性。我发现自己在写C语言的时候,总是不自觉地就引入了高级
    发表于 05-09 18:16 1次下载
    <b class='flag-5'>C</b><b class='flag-5'>语言</b>和<b class='flag-5'>C</b>++编程的<b class='flag-5'>一些</b>思考资料<b class='flag-5'>说明</b>

    一些基础的C语言程序及其源代码资料合集免费下载

    本文档的主要内容详细介绍的是一些基础的C语言程序及其源代码资料合集免费下载。
    发表于 05-21 08:00 3次下载
    <b class='flag-5'>一些</b>基础的<b class='flag-5'>C</b><b class='flag-5'>语言</b>程序及其源<b class='flag-5'>代码</b>资料合集免费下载

    单片机C语言代码编写技巧

    下面发一些我在网上看到的单片机C语言代码编写技巧和自己的一些经验来和大家分享;
    发表于 07-14 11:02 2906次阅读

    关于C语言一些特殊功能介绍

    C语言之所以那么受欢迎,除了C语言历史悠久之外,还有它具有一些编程语言没有的功能。那么,今年我们
    的头像 发表于 08-18 15:31 2403次阅读
    关于<b class='flag-5'>C</b><b class='flag-5'>语言</b>的<b class='flag-5'>一些</b>特殊功能介绍

    通过一些附加信息和有用的实现技术对C函数的探索

    在本文中,我们将通过一些附加信息和一些有用的实现技术来结束对C函数的探索。 基本的C函数(例如,
    的头像 发表于 09-27 11:11 1531次阅读

    C语言常见的一些标准库

    有很多工程师喜欢自己封装一些标准库已有的函数,其实自己封装的函数,并不定比标准库好,有时候反而代码更冗余,且有bug。下面就来分享C
    的头像 发表于 11-18 16:22 3121次阅读

    C语言一些常用标准库分享

     有很多工程师喜欢自己封装一些标准库已有的函数,其实自己封装的函数,并不定比标准库好,有时候反而代码更冗余,且有bug。下面就来分享C
    的头像 发表于 11-22 11:54 2802次阅读

    C语言和STM32学习的一些学习笔记

    自己总结的一些C语言和STM32F1学习的一些笔记,适合想快速了解学习C语言和STM32单片机的
    发表于 03-24 14:53 36次下载

    分享一些Python代码加速工具

    这篇文章会提供一些优化代码的工具。会让代码变得更简洁,或者更迅速。
    发表于 07-07 11:18 373次阅读

    C语言如何写出高效代码呢?

    当涉及复杂的高效C代码案例时,这些代码示例展示了C语言中一些复杂且高效的应用案例,涵盖了排序算法、图算法、位操作、文件操作、多线程编程等领域
    发表于 09-06 14:57 491次阅读
    <b class='flag-5'>C</b><b class='flag-5'>语言</b>如何写出高效<b class='flag-5'>代码</b>呢?

    单片机C代码嵌套汇编的一些方法

    单片机C代码嵌套汇编的一些方法
    的头像 发表于 10-18 16:39 511次阅读
    单片机<b class='flag-5'>C</b><b class='flag-5'>代码</b>嵌套汇编的<b class='flag-5'>一些</b>方法