C++反射实现

内容来自别人的内容 记录下

1.需要一个单例模式Singleton.h

#pragma once

 
template 
class Singleton
{
public:
    static T * instance()
    {
        if (m_instance == NULL)
            m_instance = new T();
        return m_instance;
    }
 
private:
    Singleton() {}
    Singleton(const Singleton &);
    Singleton & operator = (const Singleton &);
    ~Singleton() {std::cout<<"Descontructor :"<
T * Singleton::m_instance = NULL;

2.类成员 ClassField.h

#pragma once
 
#include 
using namespace std;
 
 
class ClassField
{
public:
    ClassField() : m_name(""), m_type(""), m_offset(0) {}
    ClassField(const string & name, const string & type, size_t offset) : m_name(name), m_type(type), m_offset(offset) {}
    ~ClassField() {}
 
    const string & name()
    {
        return m_name;
    }
 
    const string & type()
    {
        return m_type;
    }
 
    size_t offset()
    {
        return m_offset;
    }
 
private:
    string m_name;
    string m_type;
    size_t m_offset;
};
 

3.类方法 ClassMethod.h

#pragma once
 
#include 
using namespace std;
 
 
class ClassMethod
{
public:
    ClassMethod() : m_name(""), m_method(0) {}
    ClassMethod(const string & name, uintptr_t method) : m_name(name), m_method(method) {}
    ~ClassMethod() {}
 
    const string & name()
    {
        return m_name;
    }
 
    uintptr_t method()
    {
        return m_method;
    }
 
private:
    string m_name;
    uintptr_t m_method;
};
 

4.注册类 ClassReg.h

#pragma once

#include "ReflexBase.h"

 

class ClassRegister
{
public:
    ClassRegister(const string & className, create_object method)
    {
        // register class
        Singleton::instance()->register_class(className, method);
    }
 
    ClassRegister(const string & className, const string & fieldName, const string & fieldType, uintptr_t offset)
    {
        // register class field
        Singleton::instance()->register_class_field(className, fieldName, fieldType, offset);
    }
 
    ClassRegister(const string & className, const string & methodName, uintptr_t method)
    {
        // register class method
        Singleton::instance()->register_class_method(className, methodName, method);
    }
};
 

#if 0

#define REGISTER_CLASS(className)                                       \
    Object * createObject##className()                                  \
    {                                                                   \
        Object * obj = new className();                                 \
        obj->set_class_name(#className);                                \
        return obj;                                                     \
    }                                                                  	\
    ClassRegister classRegister##className(#className, createObject##className)
#else
#define REGISTER_CLASS(className)                                       \
		  IQMCY * createObject##className()											 \
		  {																						 \
				IQMCY * obj = new className();											 \
				obj->set_class_name(#className); 										 \
				return obj; 																	 \
		  }																						 \
		  ClassRegister classRegister##className(#className, createObject##className)

#endif
 
#define REGISTER_CLASS_FIELD(className, fieldName, fieldType) \
    className className##fieldName; \
    ClassRegister classRegister##className##fieldName(#className, #fieldName, #fieldType, (size_t)(&(className##fieldName.fieldName)) - (size_t)(&className##fieldName))
 
#define REGISTER_CLASS_METHOD(className, methodName, returnType, ...) \
    std::function className##methodName##method = &className::methodName; \
    ClassRegister classRegister##className##methodName(#className, #methodName, (uintptr_t)&(className##methodName##method))

5.基类ReflexBase.h

#pragma once

#include 
#include 
#include
#include
#include

#include
#include 
#include 
#include 



#include

#include "httplib.h"

#include "md5.h"
#include "base64.h"
#include "des.h"
#include "utils.h"



#include "zlog.h" 



#include 
#include 
#include 
#include 
#include 





using namespace std;
 
#include "Singleton.h"

 
#include "ClassField.h"
#include "ClassMethod.h"
 
#if 1

#include "zlog.h"
#include "IBase.h"


#endif
 
class IQMCY
{
public:
    IQMCY();
    virtual ~IQMCY();

	
    void set_class_name(const string & className);
    const string & get_class_name() const;
 
    int get_field_count();
    ClassField * get_field(int pos);
    ClassField * get_field(const string & fieldName);
 
    template 
    void get(const string & fieldName, T & value);
 
    template 
    void set(const string & fieldName, const T & value);
    void set(const string & fieldName, const char * value);
    
    template 
    R call(const string & methodName, Args... args);


#if 1 

	using MessageWatcher = std::function;
	using LedResponse = std::function;


	virtual int LED_Open(std::string snid,std::string ip,std::string resolution,int port,std::string bmsid,std::string server_ip,int server_port,bool encrypt,bool isDebugMode) = 0;
	virtual STATUS_CODE NVR_SetLED(PLAYLIST *playlist) = 0;		
	virtual STATUS_CODE NVR_GetLEDState() = 0;				
	virtual std::string NVR_GetBrand() = 0;		
	virtual std::pair NVR_GetStatus() = 0; 			
	std::pair NVR_GetActiveTime() ;

	void NVR_SetKeepLiveTime(int time) ;		
public:		

	MessageWatcher m_cb;
	LedResponse m_socket_cb = nullptr;	
	bool m_run_flag;						
	bool m_debug_mode;			
	uint64_t m_counter = 0;
protected:		
	virtual int NVR_Close(void) =0; 	
	virtual void NVR_UpdateActiveTime() final;
	void NVR_SetCB(MessageWatcher);
	void NVR_SetRecvCB(LedResponse); 	
	void NVR_Response(std::string &content);		
	void NVR_DefaultCB(std::string &content);
	int NVR_Fly2LEDEx(int cmd,char *data,int len);		
	int NVR_Fly2LED(int cmd,char *data,int len);

	int NVR_CreateSocket(const char *led_ip,int port);
	int CreateAsyncSocket(const char *led_ip,int port, int time_out);

	void PrintHex(unsigned char *data,int len);
	unsigned short NVR_GetCRC( unsigned char* buffer, int buffer_length);
	std::string m_ip;
	std::string m_resolution;
	std::string m_bmsid; 	
	std::string m_task_id;				
	
	std::mutex m_led_mutex;
	
	std::string m_server_ip;
	std::string m_snid;
	std::string m_fault_msg;
	int m_server_port;
	int m_led_socket;
	bool m_encrypt = false;

	int	m_status;
	int	m_result;		
	int	m_port;

	std::atomic m_last_acess_time;
	int m_keep_live_time;
#endif
	 
protected:
    string m_className;
};
 
typedef IQMCY * (*create_object)(void);
 
class ClassFactory
{
    friend class Singleton;
public:
    // reflect class
    void register_class(const string & className, create_object method);
    IQMCY * create_class(const string & className);
 
    // reflect class field
    void register_class_field(const string & className, const string & fieldName, const string & fieldType, size_t offset);
    int get_class_field_count(const string & className);
    ClassField * get_class_field(const string & className, int pos);
    ClassField * get_class_field(const string & className, const string & fieldName);
 
    // reflect class method
    void register_class_method(const string & className, const string &methodName, uintptr_t method);
    int get_class_method_count(const string & className);
    ClassMethod * get_class_method(const string & className, int pos);
    ClassMethod * get_class_method(const string & className, const string & methodName);
 
private:
    ClassFactory() {}
    ~ClassFactory() {std::cout<<__func__< m_classMap;
    std::map> m_classFields;
    std::map> m_classMethods;
};
 
template 
void IQMCY::get(const string & fieldName, T & value)
{
    ClassField * field = Singleton::instance()->get_class_field(m_className, fieldName);
    size_t offset = field->offset();
    value = *((T *)((unsigned char *)(this) + offset));
}
 
template 
void IQMCY::set(const string & fieldName, const T & value)
{
    ClassField * field = Singleton::instance()->get_class_field(m_className, fieldName);
    size_t offset = field->offset();
    *((T *)((unsigned char *)(this) + offset)) = value;
}
 
template 
R IQMCY::call(const string & methodName, Args... args)
{
    ClassFactory * factory = Singleton::instance();
    ClassMethod * method = factory->get_class_method(m_className, methodName);
    auto func = method->method();
    typedef std::function class_method;
    return (*((class_method *)func))(this, args...);
}
 

6.基类CPPReflexBase.cpp

#include "ReflexBase.h"

#include 
#include "json.hpp"
#include 

 
void IQMCY::set_class_name(const string & className)
{
    m_className = className;
}
 
const string & IQMCY::get_class_name() const
{
    return m_className;
}
 
int IQMCY::get_field_count()
{
    return Singleton::instance()->get_class_field_count(m_className);
}
 
ClassField * IQMCY::get_field(int pos)
{
    return Singleton::instance()->get_class_field(m_className, pos);
}
 
ClassField * IQMCY::get_field(const string & fieldName)
{
    return Singleton::instance()->get_class_field(m_className, fieldName);
}
 
void IQMCY::set(const string & fieldName, const char * value)
{
    ClassField * field = Singleton::instance()->get_class_field(m_className, fieldName);
    size_t offset = field->offset();
    *((string *)((unsigned char *)(this) + offset)) = string(value);
}
 
void ClassFactory::register_class(const string & className, create_object method)
{
	 std::cout<<"register_class "<second()<second();
}
 
void ClassFactory::register_class_field(const string & className, const string & fieldName, const string & fieldType, size_t offset)
{
    m_classFields[className].push_back(new ClassField(fieldName, fieldType, offset));
}
 
int ClassFactory::get_class_field_count(const string & className)
{
    return m_classFields[className].size();
}
 
ClassField * ClassFactory::get_class_field(const string & className, int pos)
{
    int size = m_classFields[className].size();
    if (pos < 0 || pos >= size)
    {
        return nullptr;
    }
    return m_classFields[className][pos];
}
 
ClassField * ClassFactory::get_class_field(const string & className, const string & fieldName)
{
    auto fields = m_classFields[className];
    for (auto it = fields.begin(); it != fields.end(); it++)
    {
        if ((*it)->name() == fieldName)
        {
            return *it;
        }
    }
    return nullptr;
}
 
void ClassFactory::register_class_method(const string & className, const string &methodName, uintptr_t method)
{
    m_classMethods[className].push_back(new ClassMethod(methodName, method));
}
 
int ClassFactory::get_class_method_count(const string & className)
{
    return m_classMethods[className].size();
}
 
ClassMethod * ClassFactory::get_class_method(const string & className, int pos)
{
    int size = m_classMethods[className].size();
    if (pos < 0 || pos >= size)
    {
        return nullptr;
    }
    return m_classMethods[className][pos];
}
 
ClassMethod * ClassFactory::get_class_method(const string & className, const string & methodName)
{
    auto methods = m_classMethods[className];
    for (auto it = methods.begin(); it != methods.end(); it++)
    {
        if ((*it)->name() == methodName)
        {
            return *it;
        }
    }
    return nullptr;
}

#if 1

void IQMCY::NVR_DefaultCB(std::string &content)
{
	std::cout<<__FUNCTION__< IQMCY::NVR_GetActiveTime()
{
	std::pairret;
	return std::make_pair(m_last_acess_time.load(),m_keep_live_time);
}


unsigned short IQMCY::NVR_GetCRC(unsigned char* buffer, int buffer_length)
{
	unsigned char c, treat, bcrc;
	unsigned short wcrc = 0;
	int i,j;
    for (i = 0; i < buffer_length; i++) 
	{
        c = buffer[i];
        for (j = 0; j < 8; j++) 
		{
            treat = c & 0x80;
            c <<= 1;
            bcrc = (wcrc >> 8) & 0x80;
            wcrc <<= 1;
            if (treat != bcrc)
                wcrc ^= 0x1021;
        }
    }
    return wcrc;
}


void IQMCY::PrintHex(unsigned char *data,int len)
{
	printf("~~~~~~~~~~~~~~~~~~~~~~~~\n");
	for(int i = 0;i0)
	{

		if(m_socket_cb)
		{
			m_socket_cb(cmd,buffer,recv_len);
		}
	}
	else
	{
		printf("\nCan not get reply from Server\n");		
		close(socket_fd);
		if(m_socket_cb)
		{
			buffer[0] = ERROR_NODATA;
			m_socket_cb(cmd,buffer,1);
		}		
		return -3;
	}

	close(socket_fd);

	return 0;
}



int IQMCY::NVR_Fly2LED(int cmd,char *data,int len)
{
	unsigned char buffer[2048]={0};
	int recv_len = 0,ret = 0;


	ret = write(m_led_socket,data,len);

	if(ret 0)
	{
		if(m_socket_cb)
		{
			m_socket_cb(cmd,buffer,recv_len);
		}
	}
	else
	{
		printf("\nCan not get reply from Server\n");		
		//close(socket_fd);
		if(m_socket_cb)
		{
			buffer[0] = ERROR_NODATA;
			m_socket_cb(cmd,buffer,1);
		}		
		return -3;
	}

	//close(socket_fd);

	//std::cout<<__func__ <<" exit !!!!"<

7.子类头文件

#pragma once
 
#include 
using namespace std;
 
#include "ClassReg.h"
 


class LED_3SV6:public IQMCY
{
public:
    LED_3SV6() : m_name("a"), m_age(18) {
		m_key_id = 0;
		m_status = -1;
		m_fault_msg.clear();
		std::cout<<__func__<NVR_GetStatus();



protected:		
	virtual int NVR_Close() ;

private:

	bool m_is_last_packet;
	int m_led_status;
	CameraItem m_cameras; //camera index,ip 			

	//std::future m_exec_result;			
	std::string m_playlist;
	std::string m_playFilename;

	int m_key_id;
	enum OP_TYPE
	{
		OP_UPDATE =1,
		OP_TRANSFER,
	};
	
	OP_TYPE m_op;
	
	bool SendCommand(unsigned code, std::string &sendData);
	bool SendAsync(unsigned code, std::string &sendData); 	
	int UploadData(char *filedata,char *filename,int filelen);
	int TransferData(char *data,char *filename,int len);
	int BuildPacket(unsigned char devAddr, unsigned char cmd, char* data, int len, char** dest);
	unsigned char * BuildEncryptPacket(unsigned char*in_data, int in_len, int *out_len);		
	int Convert2LedData(unsigned char devAddr, unsigned char cmd, char* data, int len, char** dest);		
	int encode_frame(char* source, int sourceLength, char* dest, int* destLength);
	int decode_frame(char* source, int sourceLength, char* dest, int* destLength);
	int make_file_data_pkt(unsigned char devAddr, char* szFileName, int nFileOffset, char* data, int len, char** pFrame);
	int make_download_pkt(unsigned char devAddr, char* szFileName, int nFileOffset, char** pFrame); 	
	void ReceiveCB(int,unsigned char *data,int len);
	void DisplayResponse(unsigned char *data,int len);
	void GetStatusResponse(unsigned char *data,int len);
	void UploadResponse(unsigned char *data,int len);		
	int GetPlayList();
	int GetBright();


public:
    string m_name;
    int m_age;
};


8.子类cpp文件 


#include"LED_3SV6.h"

using namespace std;


#define FRAME_HEDAD_BYTE 0x02 // 帧头
#define FRAME_TAIL_BYTE 0x03 // 帧尾
#define SWAP_DWORD(w) (((((unsigned int)w) >> 24) & 0xFF) | ((((unsigned int)w) >> 8) & 0x0000FF00) | ((((unsigned int)w) << 8) & 0x00FF0000) | ((((unsigned int)w) << 24) & 0xFF000000))

#define MAX_BUF_SIZE 	4096

#define CMD_DISPLAY		0
#define CMD_GETSTATUS	1
#define CMD_DOWNLOAD		2
#define CMD_UPLOAD		3



static const char *g_keys[10]={
"microvid",
"microvid",
"microvid",
"microvid",
"microvid",
"microvid",
"microvid",
"microvid",
"microvid",
"microvid"
};



static const char *g_fault_info[10]={
	"",
	"控制器故障",
	"显示模组故障",
	"",
	"单像素管故障",
	"检测系统故障",
	"输入交流电220V故障",
	"防雷器故障",
	"光敏部件故障",
	"温度异常故障"
};


static unsigned char reply_data[]={
	0xFB,0xFB,0xFB,0xFB,0xAA,0x00,0x00,0x00,0x02,0x00,
	0x33,0x69,0x7E,0xED,0xDA,0x6A,0x8C,0x4F,0x6D,0xAC,
	0xB9,0x3C,0xDE,0x85,0x97,0xCE,0x40,0x59,0xA9,0x97,
	0xDB,0xD7,0x23,0xBE,0xC3,0x80,0x83,0xE5,0xA5,0x4C,
	0xE4,0xB4,0xFD,0x65,0x2B,0x55,0x64,0xBF,0x8E,0x4A,
	0x01,0x7B,0x4E,0xA3,0xDA,0xCB,0xE2,0x8B,0xB3,0xB9,
	0xB7,0x7E,0x39,0xAB,0x86,0x82,0x0F,0x1F,0x25,0x41,
	0x31,0x5A,0xE8,0x06,0x87,0xB3,0x69,0x24,0xB7,0xB0,
	0xA7,0x6C,0x27,0x2E,0xF5,0x92,0xC5,0x85,0xAC,0x0B,
	0xD4,0xD1,0xE4,0x77,0x90,0x3B,0x00,0x3F,0x37,0x4A,
	0xC1,0x35,0xE1,0xA5,0x9F,0x4B,0xC4,0x3C,0x8E,0x55,
	0x1E,0xFA,0xD3,0xAE,0x19,0x58,0x40,0x86,0x09,0x74,
	0x7A,0xC2,0x31,0xB5,0x24,0x0A,0x27,0xCF,0xFB,0xC6,
	0x37,0xEB,0xB9,0x2B,0x1C,0x09,0xDD,0x10,0x37,0x4A,
	0xC1,0x35,0xE1,0xA5,0x9F,0x4B,0xA9,0x94,0xD1,0x9F,
	0x6B,0xBE,0xE0,0xC4,0x53,0xD0,0xAC,0xBE,0x6A,0x27,
	0x42,0xD1,0xB0,0xEA,0x2D,0xD7,0x1B,0x91,0x4B,0x55,
	0x8B,0xAF,0xB9,0xA2,0xBB,0xB4,0x04,0x78,0xFE,0xFE,0xFE,0xFE
};


static unsigned char reply_test_data[]={

	0xFB,0xFB,0xFB,0xFB,0x12,0x00,0x00,0x00,0x00,0x00,
	0x15,0x5F,0xF7,0x8F,0x8F,0x33,0x24,0x94,0x86,0x53,
	0x49,0xC9,0xBD,0x9D,0x5B,0x41,0xFE,0xFE,0xFE,0xFE
};

static unsigned char* ParseData(unsigned char * data,int len,int* out_len,int key_id)
{
	char valid_data = 0;
	unsigned char *parse_result=NULL;
	int encrypt_size = 0;
	*out_len = 0;	

	printf("ParseData encrypted begin*************************\n");

	printf("(uint32_t*)data = %08X\n",*((uint32_t*)data));

	if(*((uint32_t*)data) == 0xFBFBFBFB)
	{
		printf("Find head flag\n");
		if(*((uint32_t *)(data+len-4)) == 0xFEFEFEFE)
		{
			printf("Find end flag valid data\n");			
			valid_data = 1;
		}
	}


	if(valid_data)
	{
		encrypt_size = len-14;
		
		unsigned char *encrypt_data = (unsigned char *)malloc(len-14);
		memcpy(encrypt_data,data+10,encrypt_size);


		printf("Get encryptdata:\n");
		for(int i = 0;i 0)
		{
			close(m_led_socket);
			m_led_socket = 0;
			m_is_last_packet = true;					
		}

	}
	else
	{
		if(m_encrypt)
		{
			//如果启动加密 需要先解密
			plain_data = ParseData(data,len,&out_len,m_key_id);
			if(plain_data == NULL)
			{
				std::cout<<"ParseData get null data"<preset_data_size)
		{
			std::cout<<"Receive data is too large!!!!"<preset_data_size)
		{
			std::cout<<"Receive data is too large!!!!"<>i) & 1 )== 1)
					{
						m_fault_msg.append(g_fault_info[i]);
						m_fault_msg.append("/");						
					}
				}
			}
		}
		else
		{
			std::cout<<"Get status data is not valid :["<>8 &0xFF;
	packet_buff[6] = data_len>>16 &0xFF;
	packet_buff[7] = data_len>>24 &0xFF;

	//printf("data_len:%d packet:[%02x %02x %02x %02x]\n",data_len,packet_len[0],packet_len[1],packet_len[2],packet_len[3]);


	//Op code:1 for update key ,2 for normal upload data

	packet_buff[8] = m_op;
	packet_buff[9] = m_key_id;

	memcpy(packet_buff+10,encrypt_data,encrypt_size);

	//End flag:4 bytes 0xFEFEFEFE

	memset(packet_buff+packet_size-4,0xFE,4);

	m_op = OP_TRANSFER; 

	if(m_debug_mode)
	{
		printf(">>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>\n");
		for(int i = 0;i 0) 
	{
        rc = encode_frame(data, len, pDest, &destLength);
        if (rc < 0) {
            return -1;
        }
        pDest += destLength;
    }

    int nCRCDataLength = 2 + 2 + len;
    char* pCRCBuffer = new char[nCRCDataLength];
    memcpy(pCRCBuffer + 0, szFrameAddr, 2);
    memcpy(pCRCBuffer + 2, szFrameType, 2);
    if (len > 0) {
        memcpy(pCRCBuffer + 4, data, len);
    }

	
    unsigned short wCRCValue = NVR_GetCRC((unsigned char*)pCRCBuffer, nCRCDataLength);
    *pDest++ = wCRCValue / 256;
    *pDest++ = wCRCValue % 256;

    delete[] pCRCBuffer;


    *pDest++ = (char)FRAME_TAIL_BYTE;

    return (short)(pDest - *dest);

    return rc;
}



int LED_3SV6::make_download_pkt(unsigned char devAddr, char* szFileName, int nFileOffset, char** pFrame)
{
    // 文件名(不定长 ASCII 码字符串) + 文件指针偏移(4字节网络字节序)
    int rc = -1;
    char* pFrameData = NULL;
    // 包含最后\0
    int nFileNameLength = strlen(szFileName) + 1;

    // 文件内容偏移
    unsigned int dwOffset = SWAP_DWORD(nFileOffset);

    int nTotalLength = nFileNameLength + sizeof(dwOffset);
    pFrameData = new char[nTotalLength];
    if (pFrameData == NULL) {
        return -1;
    }
    memcpy(pFrameData, szFileName, nFileNameLength);
    memcpy(pFrameData + nFileNameLength, &dwOffset, sizeof(dwOffset));

    rc = Convert2LedData(devAddr, 9, pFrameData, nTotalLength, pFrame);
    delete[] pFrameData;

    return rc;
}



int LED_3SV6::make_file_data_pkt(unsigned char devAddr, char* szFileName, int nFileOffset, char* data, int len, char** pFrame)
{
    int rc = -1;
    // 文件名(play.lst) + 0x2B + 文件指针偏移(4字节 大端) + 文件内容(不定长)
    int nFileNameLength = 0;
    char* pBuffer = NULL;
    int nTotalLength = 0;
    char* pFrameData = NULL;
    unsigned int dwFileOffsetNetOrder = (unsigned int)nFileOffset;
    if (!((len == 0) || (len > 0 && len <= 2048))) {
        return -1;
    }

    nFileNameLength = strlen(szFileName);
    if (nFileNameLength <= 0) {
        return -1;
    }
    nTotalLength = nFileNameLength + 1 + 4 + len;
    pBuffer = new char[nTotalLength];
    if (pBuffer == NULL) {
        return -1;
    }
    pFrameData = pBuffer;

    // 复制文件名
    memcpy(pBuffer, szFileName, nFileNameLength);
    pBuffer += nFileNameLength;

    // 文件名结束字符:0x2B
    *pBuffer++ = 0x2B;

    // 文件偏移
    dwFileOffsetNetOrder = SWAP_DWORD(dwFileOffsetNetOrder);
    memcpy(pBuffer, &dwFileOffsetNetOrder, 4);
    pBuffer += 4;

    // 文件内容
    if (len > 0) {
        memcpy(pBuffer, data, len);
    }

    //rc = make3sV6Frame(devAddr, 10, pFrameData, nTotalLength, pFrame);
	rc = Convert2LedData(devAddr, 10, pFrameData, nTotalLength, pFrame);	
    delete[] pFrameData;

    return rc;
}








int LED_3SV6::UploadData(char *filedata,char *filename,int filelen)
{
    const int BLOCK_SIZE = 2048;
    int frame_num = filelen / BLOCK_SIZE + 1;
    int len = 0;
    int i, nPktLength;

    char* pFrame = NULL;

    for (i = 0; i < frame_num; i++) 
	{
        int nFileOffset = i * BLOCK_SIZE;
        if (i == frame_num - 1) {
            len = filelen - BLOCK_SIZE * i;
        } else {
            len = BLOCK_SIZE;
        }


		pFrame = nullptr;

        nPktLength = make_file_data_pkt(0, filename, nFileOffset, filedata + nFileOffset, len, &pFrame);

		PrintHex((unsigned char *)pFrame,nPktLength);

		if(pFrame && nPktLength>0)
		{
			if(m_encrypt)
			{
				int out_len = 0;
				unsigned char *encrypt_data = BuildEncryptPacket((unsigned char * )pFrame, nPktLength, &out_len);

				if(encrypt_data == NULL)
				{
					std::cout<<"BuildEncryptPacket get null data"<0)
		{
			printf("Send [%d] packet of total [%d]\n",i+1,frame_num);

			if(m_encrypt)
			{
				int out_len = 0;
				unsigned char *encrypt_data = BuildEncryptPacket((unsigned char * )pFrame, nPktLength, &out_len);

				if(encrypt_data == NULL)
				{
					std::cout<<"BuildEncryptPacket get null data"<screen_items[0].line_items[0].osd_str< lock(m_led_mutex);

	std::cout<<"Begin execute task>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>"<screen_items.size();

	 zlog_info(g_zlog,"NVR_SetLED screen size[%d] task id = [%s] bmsid [%s]",
	 	screen_size,playlist->playlist_id.c_str(),playlist->bmsid.c_str());
	
	 char temp[200] = { 0 };

	snprintf(temp, sizeof(temp) - 1, "[%s]\r\nitem_no=%d\r\n", m_playlist.c_str(), screen_size);

	led_output = temp;

	m_task_id = playlist->playlist_id;			
	m_is_last_packet = false;

	if(m_led_socket>0)
	{
		close(m_led_socket);
		m_led_socket = 0;
		printf("m_led_socket [%d]> 0 need Close socket \n",m_led_socket); 	
		
	}
	
	m_led_socket = NVR_CreateSocket(m_ip.c_str(), m_port);
	if(m_led_socket == -1)
	{
		printf("Failed Cannot connect to led \n");		
		m_led_socket	 = 0;
		FeedBack2Server(m_server_ip, m_server_port,m_bmsid ,m_task_id,ERROR_NETWORK);

		zlog_fatal(g_zlog,"NVR_SetLED NVR_CreateSocket failed ip[%s] port[%d]  bmsid [%s]",
			m_ip.c_str(),m_port,playlist->bmsid.c_str());

		return ERROR_NETWORK;
	}

	for(int i = 0;iscreen_items[i];
		memset(temp,0,200);

		auto line_size = screen.line_items.size();
		auto j= screen.line_items.size();		

		for(j = 0;j< line_size; j++)
		{
			LINE_ITEM &line = screen.line_items[j];

			if(line.is_image)
			{
				char *pRawContent= new char[line.osd_str.size()];
				int nRawContentLength = f_base64_decode(pRawContent,const_cast(line.osd_str.c_str()));
				printf("f_base64_decode nRawContentLength=%d\n",nRawContentLength);
				std::string shortname;
				
				char img_sn[50] = {0};

				if( nRawContentLength > 0 )
				{
					sprintf(img_sn,"%03d",i);
					shortname.append("./png/");
					shortname.append(img_sn);
					shortname.append(".png");					
					//shortname = +img_sn+".bmp";
					//shortname = std::to_string(j)+"003";
					std::string img_name = APP_LOG_IMAGE_DIR + playlist->bmsid+"_"+img_sn+".png";
					printf("Save file name[%s]\n",img_name.c_str());
					zlog_info(g_zlog,"[%d] screen type:Image file name[%s] led target name[%s] size[%d]\n",i+1,
						img_name.c_str(),shortname.c_str(),nRawContentLength);
					FILE * fp = fopen(img_name.c_str(),"wb+");
					if(fp)
					{
						fwrite(pRawContent,nRawContentLength,1,fp);
						fclose(fp);
					}
				
					//line_item.image_size = nRawContentLength;
					printf("Image transfer filename[%s] size[%d]\n",shortname.c_str(),nRawContentLength);					
					auto ret = TransferData((char *)pRawContent, (char *)shortname.c_str(), nRawContentLength);
					if(ret == -1)
					{
						delete[]pRawContent;						
						return ERROR_EXEC;
					}
				}
				delete[]pRawContent;
				

				if(j == 0)
				{
					snprintf(temp, sizeof(temp) - 1, "item%d=%d,%d,0,", i, line.display_time * 100, 1);
					led_output+= temp;
				}
				
				//生成播放表
				char szLine[100] = { 0 };
				sprintf(szLine, "\\C%03d%03d\\P%s", line.pos_x, line.pos_y, img_sn);
				led_output+= szLine;
				
			}
			else
			{
				const char* font = line.fontname.c_str();
				int fontSize = line.fontsize;
				char szFont[64] = { 0 };

				if(j == 0)
				{
					snprintf(temp, sizeof(temp) - 1, "item%d=%d,%d,0,", i, line.display_time * 100, 1);
					led_output+= temp;
					
				}
				
				if (strcmp(font, "黑体") == 0) {
				 snprintf(szFont, sizeof(szFont) - 1, "\\fh%02d%02d", fontSize, fontSize);
				} else if (strcmp(font, "楷体") == 0) {
				 snprintf(szFont, sizeof(szFont) - 1, "\\fk%02d%02d", fontSize, fontSize);
				} else if (strcmp(font, "隶书") == 0) {
				 snprintf(szFont, sizeof(szFont) - 1, "\\fl%02d%02d", fontSize, fontSize);
				} else {
				 snprintf(szFont, sizeof(szFont) - 1, "\\fs%02d%02d", fontSize, fontSize);
				}

				char szLine[600] = { 0 };
				char gbk[500] = {0};
				
				UTF8TOGBK((char *)line.osd_str.c_str(),line.osd_str.size(),gbk,500);

				zlog_info(g_zlog,"[%d] screen [%d] line type:text Set OSD [%s] size[%d] fontname[%s]\n",
											i+1,j+1,line.osd_str.c_str(),fontSize,font);

				sprintf(szLine, "\\C%03d%03d%s\\c%s000\\b%s000%s",
					line.pos_x, line.pos_y, szFont, line.fgcolor.c_str(), line.bgcolor.c_str(), gbk);
				 //line.pos_x, line.pos_y, szFont, line.fgcolor.c_str(), line.bgcolor.c_str(), line.osd_str.c_str());
				
				led_output+= szLine;
			}
			
		}
		led_output+="\r\n";

		usleep(1000*20);
		
	}

	if(screen_size == 0 )			//Delete All
	{
		led_output = R"([playlist]
			item_no = 1
			item0 = 500,0,0
		)";
	}

	m_is_last_packet = true;
	
	auto ret = TransferData((char *)led_output.c_str(), (char*)m_playFilename.c_str(), led_output.size());

	zlog_info(g_zlog,"NVR_SetLED ret [%d] [%s] port[%d] content[%s] ",ret,m_ip.c_str(),m_port,led_output.c_str());

	std::cout<<" TransferData content is:"<(sendData.c_str());
	}
	int rc = BuildPacket(0, code, data, sendData.size(), &pFrame);
	if (rc < 0) 
	{
	  return false;
	}

	if(m_encrypt)
	{
		int out_len = 0;
		unsigned char *encrypt_data = BuildEncryptPacket((unsigned char * )pFrame, rc, &out_len);

		if(encrypt_data == NULL)
		{
			std::cout<<"BuildEncryptPacket get null data"<(sendData.c_str());
	}
	int rc = BuildPacket(0, code, data, sendData.size(), &pFrame);
	if (rc < 0) 
	{
	  return false;
	}

	if(m_encrypt)
	{
		int out_len = 0;
		unsigned char *encrypt_data = BuildEncryptPacket((unsigned char * )pFrame, rc, &out_len);

		if(encrypt_data == NULL)
		{
			std::cout<<"BuildEncryptPacket get null data"< LED_3SV6::NVR_GetStatus()
{
	return std::make_pair(m_status,m_fault_msg);
}

std::string LED_3SV6::NVR_GetBrand()
{
	return "3SV6";	
}



int LED_3SV6::NVR_Close(void)
{
	if(m_led_socket)
	{
		close(m_led_socket);
	}

	return 0;
}



REGISTER_CLASS(LED_3SV6);

9.测试代码:

#pragma once
 
#include 
using namespace std;
 
#include "ClassReg.h"
 


class LED_XK:public IQMCY
{
public:
    LED_XK() : m_name("a"), m_age(18) {}
 
    void f1()
    {
        std::cout << "f1" << std::endl;
    }
 
    int f2(int a)
    {
        std::cout << "f2" << std::endl;
        return a;
    }
 	 virtual std::string NVR_GetBrand() {return "LED_XK";}
public:
    string m_name;
    int m_age;
};

REGISTER_CLASS(LED_XK);
#if 0

REGISTER_CLASS_FIELD(LED_XK, m_name, string);
REGISTER_CLASS_FIELD(LED_XK, m_age, int);
REGISTER_CLASS_METHOD(LED_XK, f1, void);
REGISTER_CLASS_METHOD(LED_XK, f2, int, int);

#endif

10.使用的实例:

std::shared_ptr QMCY_APP:: GetLedPointer(const string& brand)
{
	auto protocol = m_basic_info.protocal_table[brand];

	ClassFactory * factory = Singleton::instance();

	std::shared_ptr result (factory->create_class(protocol));

	if(result)
	{
		std::cout<<"result::"<get("m_name", name);
	a->set("m_name", "kitty");

	int age;
	a->get("m_age", age);
	a->set("m_age", 30);

	a->call("f1");
	int num = a->call("f2", 123);
#endif

	return nullptr;	
 }

你可能感兴趣的:(c++,开发语言)