以前也读了这个RGBD相机的一些源码但是发现自己的基本功是一点也不好,所以就搁置了很久,今天试图来回答一些问题。
说好的不会再出新品结果还是出了,估计这个市场还是可以的
自己就看一个例子里面的代码
就一个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文件夹下。
直接下来就看几个代码,是不是和学的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语言中一个很常见的错误处理方式 - 通过指针传递错误码,如果有错误,被调用的函数会设置该指针为错误值。
调用者在调用后检查该值来进行错误处理。这种方式的好处是:
在这里被定义了很多
更具体的实现
1.析构函数~rs2_context(),在rs2_context被释放时会调用ctx->stop()。这是用于停止某个线程或后台服务。
2. 一个std::shared_ptr成员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语言常见的错误返回方式。
包含了以下字段:
c++
struct rs2_error
{
std::string message; // 错误消息
std::string function; // 函数名
std::string args; // 函数参数
rs2_exception_type exception_type; // 错误类型
};
如果一个函数返回一个结构体类型的值,那么需要使用一个结构体类型的变量来接收这个返回值。因为结构体类型通常比较大,如果直接将结构体类型的值作为函数的返回值返回,会导致复制整个结构体的内存空间,从而影响程序的性能。因此,C 语言中通常使用指向结构体的指针作为返回值,而不是直接返回结构体类型的值。
#include <stdio.h>
#include <stdlib.h>
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\n", p->name);
printf("Age: %d\n", p->age);
free(p);
}
return 0;
}
完整代码
看这个
在上面的例子中,create_person()
函数返回一个指向:
struct person
结构体的指针。
该函数使用malloc()
函数动态分配内存来存储结构体,然后将结构体的成员赋值为传入的参数。最后,该函数返回指向该结构体的指针。在 main()
函数中,调用 create_person()
函数来创建一个结构体实例,并打印出其成员的值。在使用完结构体后,还需要调用 free()
函数来释放动态分配的内存。
更具体的来分析:
struct person* p = (struct person*) malloc(sizeof(struct person));
使用malloc()获取内存,强制类型转换为需要的指针类型,使用后释放内存。
https://www.intelrealsense.com/
https://github.com/IntelRealSense/librealsens