openni框架是一套开源的SDK,用于开发3D传感器的中间层和应用层。
各个传感器需要实现OniDriverAPI.h中定义的接口,具体实现在OpenNI2/Source/Drivers目录下,不同传感器编译成不同的动态库。
openni::initialize()用于加载各个传感器的动态库,并获得动态库接口的地址。上层调用最终是调用到传感器的动态库中。
下面简单看下initialize的过程:
1.解析OpenNI.ini 2.OpenNI.ini的Drivers;Repository指定目录下的所有传感器动态库都实现了一组相同的接口(定义在OniDriverAPI.h)。 对每一个传感器动态库,dlopen打开,获得动态库句柄,dlsym获得接口地址,创建DriverHandler维护这组接口。
下图是应用层Device::open()的过程:
用到的几个系统函数说明:
1.int dladdr(void *address, Dl_info *dlip) 确定address是否位于构成进程的地址空间的其中一个加载模块(可执行库或共享库)内,如果指定的address在其中一个加载模块的范围内,则Dl_info的结构成员由dladdr()设置。 struct{ const char *dli_fname; void *dli_fbase; const char *dli_sname; void *dli_saddr; size_t dli_size; /* ELF only */ int dli_bind; /* ELF only */ int dli_type; }; dli_fname:一个指针,指向包含address的加载模块的文件名。每次调用dladdr() 后,该内存位置的内容都可能发生更改。 2.void* dlopen( const char * pathname, int mode); 打开一个动态链接库,并返回动态链接库的句柄。 3.void*dlsym(void*handle,constchar*symbol) 根据动态链接库句柄与符号,返回符号对应的地址,可以获取函数地址也可以获取变量地址。