本开发同样适用于Ultraleap Stereo IR170
1、官网下载SDK
SDK
API
值得说明的是,IR170这块开发板提供的API是基于C语言的,与LeapMotion提供的基于C++的API不同,但配置过程基本相同。
2、配置环境
添加附加依赖项
项目-属性-连接器-输入-附加依赖项添加LeapC.lib
添加包含目录和库目录
包含目录: D:\CODING\LeapCEnv\LeapCEnv\LeapSDK\include
库目录:D:\CODING\LeapCEnv\LeapCEnv\LeapSDK\lib\x64
官方提供的SDK里,LeapSDK\lib下包含x64和x86,需要在库目录里写明选用哪种架构,不然会报找不到lib的错误。
环境变量(实测不需要,暂时保留
完成以上两步,官网提供的sample就已经能跑了,但是有的教程里还是说明了要配置系统环境变量,所以在这里记录一下,如果以上两步之后还是有问题可以再试试这一步。
(1)把lib\x64文件夹下的LeapC.dll添加进环境变量,路径为:\LeapSDK\lib\x64
添加环境变量的作用是让你编译生成的EXE程序能访问到对应目录里的dll,如果不想添加进环境变量可以把dll拷贝进调试目录,直接把那些dll拷贝到EXE的目录就可以直接访问而不用添加环境变量。
(2)把lib\x64文件夹下的LeapC.dll拷贝进调试目录,路径为 \Code\Debug 和 \Code\Code\Debug
我不知道拷贝到哪一个Debug目录生效,可以自行排查一下。
C++调用C代码
需要注意的是,在调用Leap Motion官方提供的源码时,比如如下的ExampleConnection.h,其是C的代码,如果我们自己写的程序是CPP的,则需要在被调用C头文件中添加条件编译语句如下:
#ifdef __cplusplus
extern "C"{
#endif
// C代码
#ifdef __cplusplus
};
#endif
如:
Main.cpp
#include "ExampleConnection.h"
int64_t lastDrawnFrameId = 0;
volatile int64_t newestFrameId = 0;
void OnFrame(const LEAP_TRACKING_EVENT* frame) {
newestFrameId = (int64_t)frame->tracking_frame_id;
}
void main(){
ConnectionCallbacks.on_frame = OnFrame;
OpenConnection();
CloseConnection();
}
ExampleConnection.h
#ifdef __cplusplus
extern "C"{
#endif
#ifndef ExampleConnection_h
#define ExampleConnection_h
#include "LeapC.h"
// blabla
#ifdef __cplusplus
};
#endif
不然就会在链接时,报无法解析的外部符号的错误
3、测试
在工程中添加以下三段代码:
CallbackSample.c
#undef __cplusplus
#include <stdio.h>
#include <stdlib.h>
#include "LeapC.h"
#include "ExampleConnection.h"
static LEAP_CONNECTION* connectionHandle;
/** Callback for when the connection opens. */
static void OnConnect() {
printf("Connected.\n");
}
/** Callback for when a device is found. */
static void OnDevice(const LEAP_DEVICE_INFO *props) {
printf("Found device %s.\n", props->serial);
}
/** Callback for when a frame of tracking data is available. */
static void OnFrame(const LEAP_TRACKING_EVENT *frame) {
printf("Frame %lli with %i hands.\n", (long long int)frame->info.frame_id, frame->nHands);
for (uint32_t h = 0; h < frame->nHands; h++) {
LEAP_HAND* hand = &frame->pHands[h];
printf(" Hand id %i is a %s hand with position (%f, %f, %f).\n",
hand->id,
(hand->type == eLeapHandType_Left ? "left" : "right"),
hand->palm.position.x,
hand->palm.position.y,
hand->palm.position.z);
}
}
static void OnImage(const LEAP_IMAGE_EVENT *image) {
printf("Image %lli => Left: %d x %d (bpp=%d), Right: %d x %d (bpp=%d)\n",
(long long int)image->info.frame_id,
image->image[0].properties.width, image->image[0].properties.height, image->image[0].properties.bpp * 8,
image->image[1].properties.width, image->image[1].properties.height, image->image[1].properties.bpp * 8);
}
static void OnLogMessage(const eLeapLogSeverity severity, const int64_t timestamp,
const char* message) {
const char* severity_str;
switch (severity) {
case eLeapLogSeverity_Critical:
severity_str = "Critical";
break;
case eLeapLogSeverity_Warning:
severity_str = "Warning";
break;
case eLeapLogSeverity_Information:
severity_str = "Info";
break;
default:
severity_str = "";
break;
}
printf("[%s][%lli] %s\n", severity_str, (long long int)timestamp, message);
}
static void* allocate(uint32_t size, eLeapAllocatorType typeHint, void* state) {
void* ptr = malloc(size);
return ptr;
}
static void deallocate(void* ptr, void* state) {
if (!ptr)
return;
free(ptr);
}
void OnPointMappingChange(const LEAP_POINT_MAPPING_CHANGE_EVENT *change) {
if (!connectionHandle)
return;
uint64_t size = 0;
if (LeapGetPointMappingSize(*connectionHandle, &