在python中使用dll调用华为Sdk

书接上文,上次返回的只有字符串,还是printf的结果,在python里没法用,需要把数据返回到python的工作区才行。

基本思想

通过队列,将获得的数据发送到另一个函数中,在python中调用另一个函数就行了,这个函数是可以有返回值的。

完整代码

#include "pch.h"


#include "pch.h"
#include "HWPuSDK.h"
#include <string>
#include <stdio.h>
#include <Windows.h>
#include <csignal>
#include <iostream>
#include< queue>
#include <mutex>
using namespace std;
//互斥锁要在之前初始化
mutex m_mutex;
queue<int> testQueue;

//初始化函数--返回值0代表失败1代表成功
BOOL CamInit()
{
	// 初始化标记1为成功0为失败
	BOOL INIT_FLAG = IVS_PU_Init(3, NULL, 6060);
	//判断初始化是否成功
	if (INIT_FLAG)
	{
		printf("%s\n", "init sdk success");
	}
	else
	{
		printf("%s\n", "init sdk failed");
		//输出错误码
		ULONG error_code = IVS_PU_GetLastError();
		switch (error_code)
		{
		case 1:
			printf("%s\n", "common error");
			break;
		case 5:
			printf("%s\n", "SDK has been initialed");
			break;
		case 101:
			printf("%s\n", "SDK init connection mode error");
			break;
		case 102:
			printf("%s\n", "SDK init local IP error");
			break;
		default:
			printf("%s\n", "unknown error");
			break;
		}
	}
	return INIT_FLAG;
}

// 登录返回函数--返回正整数代表获得id返回其他代表失败
ULONG CamLogin(CHAR* ip, CHAR* user, CHAR* password)
{
	//返回正整数id
	ULONG login_id = IVS_PU_Login(ip, 6060, user, password);
	if (login_id > 0)
	{
		printf("%s\n", "get login id success");
	}
	else
	{
		printf("%s\n", "get login id failed");

		ULONG error_code = IVS_PU_GetLastError();
		switch (error_code)
		{
		case 1:
			printf("%s\n", "common error");
			break;
		case 2:
			printf("%s\n", "username or password error");
			break;
		case 4:
			printf("%s\n", "SDK not init");
			break;
		case 6:
			printf("%s\n", "SDK version not match equipment");
			break;
		case 7:
			printf("%s\n", "params is NULL");
			break;
		case 10106:
			printf("%s\n", "SDK password is init,please change");
			break;
		default:
			printf("%s\n", "unknown error");
			break;
		}
	}
	return login_id;
}



void procMetaData(PU_META_DATA* pstMetaData)
{
	INT target_type = 0;
	INT target_condition = 0;
	for (UINT uIndex = 0; uIndex < pstMetaData->usValidNumber; ++uIndex)
	{
		switch (pstMetaData->pstMetaUserData[uIndex].eType)
		{
		case 0x06000024: //目标类型 描述见数据结构
			target_type = pstMetaData->pstMetaUserData[uIndex].unMetaData.IntValue;
			break;
		case 0x06000022: //目标状态 描述见数据结构
			target_condition = pstMetaData->pstMetaUserData[uIndex].unMetaData.IntValue;
			break;
		default:
			break;
		}
	}
	m_mutex.lock();
	if (target_condition == 0x00000002)
	{
		//printf(" TRIPWIRE\n");
		if (target_type == 0x60)
		{
			//printf("CAR TRIPWIRE\n");
			testQueue.push(100);
		}
		else if (target_type == 0x61)
		{
			//printf("UNCAR TRIPWIRE\n");
			testQueue.push(200);
		}
		else if (target_type == 0x62)
		{
			//printf("PEOPLE TRIPWIRE\n");
			testQueue.push(300);
		}
	}
	m_mutex.unlock();
}


//实况回调函数
void CALLBACK fRealDataCallBack(CHAR* szBuffer, LONG lSize, VOID* pUsrData)
{
	BOOL bRet = PU_FALSE;
	//第二层元数据TYPE
	PU_META_DATA* pstMetaTargetData = NULL;
	bRet = IVS_User_GetMetaData(szBuffer, lSize, TARGET, &pstMetaTargetData);
	if ((PU_TRUE == bRet) && (NULL != pstMetaTargetData))
	{
		//printf("%s%d%s\n", "数据长度为", lSize, "字节");
		procMetaData(pstMetaTargetData);
		IVS_User_FreeMetaData(&pstMetaTargetData);
	}
}

//实况函数
ULONG Real(ULONG id)
{
	//结构体赋值
	PU_REAL_PLAY_INFO_S stRealPlayInfo = { 0 };
	//通道号
	stRealPlayInfo.ulChannelId = 101;
	//传输类型
	stRealPlayInfo.enProtocolType = PU_PROTOCOL_TYPE_TCP;
	//码流类型
	stRealPlayInfo.enStreamType = PU_VIDEO_MAIN_STREAM;
	//保活
	stRealPlayInfo.bKeepLive = TRUE;
	//码流加密方式
	stRealPlayInfo.enMediaCryptoType = PU_MEDIA_CRYPTO_NONE;
	//数据类型
	stRealPlayInfo.enVideoType = PU_VIDEO_TYPE_META;
	//媒体回调类型
	stRealPlayInfo.enMediaCallbackType = PU_MEDIA_CALLBACK_TYPE_META_FRAME;
	//元数据返回标记位置
	stRealPlayInfo.szReserved[22] = 1;
	//只返回检测框内容
	stRealPlayInfo.szReserved[23] = PU_METADATA_REQUEST_REST;
	//返回元数据时句柄为空
	stRealPlayInfo.hPlayWnd = NULL;

	//调用实时预览函数
	ULONG real_id = IVS_PU_RealPlay(id, &stRealPlayInfo, fRealDataCallBack, NULL);
	if (real_id > 0)
	{
		printf("%s\n", "get realplay id success");
	}
	else
	{
		printf("%s\n", "get realplay id failed");
		ULONG error_code = IVS_PU_GetLastError();
		switch (error_code)
		{
		case 1:
			printf("%s\n", "common error");
			break;
		case 4:
			printf("%s\n", "SDK not init");
			break;
		case 9:
			printf("%s\n", "connection error");
			break;
		case 10:
			printf("%s\n", "message send timeout");
			break;
		case 11:
			printf("%s\n", "message get timeout");
		case 15:
			printf("%s\n", "message get timeout");
			break;
		case 106:
			printf("%s\n", "wrong user id");
			break;
		case 137:
			printf("%s\n", "function use error");
			break;
		default:
			printf("%s\n", "unknown error");
			break;
		}

	}
	return real_id;
}


//数据接收,在python中循环调用
extern "C" __declspec(dllexport)  int recv()
{
	int result = 0;
	while (1)
	{
		//Sleep(100);
		m_mutex.lock();
		if (testQueue.size() == 0)
		{
			testQueue.push(0);
			m_mutex.unlock();
			return result;
		}
		else
		{
			result = testQueue.front();
			testQueue.pop();
			m_mutex.unlock();
			return result;
		}
	}

}

//事件订阅
extern "C" __declspec(dllexport)  int yxjc(CHAR * ip, CHAR * user, CHAR * password)
{
	//初始化sdk
	CamInit();
	Sleep(1 * 1000);
	//获得登录id
	ULONG id = CamLogin(ip, user, password);
	Sleep(1 * 1000);
	//实时数据返回
	int real_id = Real(id);
	return real_id;
}


//登出
extern "C" __declspec(dllexport)  BOOL out_log(ULONG id)
{
	BOOL out_flag = IVS_PU_Logout(id);
	return out_flag;
}
//清理sdk
extern "C" __declspec(dllexport)  BOOL clean()
{
	BOOL clean_flag = IVS_PU_Cleanup();
	return clean_flag;
}

点击生成,获得dll文件,在python中就可以调用了。

本代码在python中调用需要用while循环去调用,没有返回目标检测结果会返回0,有返回目标检测结果会返回对应的整形值。

注意事项

1、要对队列加锁,且要放在if语句判断外面

2、python退出的时候顺便把登录和sdk清除了,接口我都写了,但是没做异常处理,需要用到的要自己写一下

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值