#include <thrift/protocol/TBinaryProtocol.h>
#include <thrift/protocol/TJSONProtocol.h>
#include <thrift/transport/TBufferTransports.h>
#include "gen-cpp/student_types.h"
using namespace apache::thrift;
using namespace apache::thrift::transport;
using namespace apache::thrift::protocol;
using namespace std;
using namespace muduo;
using namespace muduo::net;
#include "tstthrift.h"
template<typename ThriftStruct>
std::string ThriftToString(const ThriftStruct& ts) {
using namespace apache::thrift::transport; // NOLINT
using namespace apache::thrift::protocol; // NOLINT
TMemoryBuffer* buffer = new TMemoryBuffer();
boost::shared_ptr<TTransport> trans(buffer);
TBinaryProtocol protocol(trans);
ts.write(&protocol);
uint8_t* buf;
uint32_t size;
buffer->getBuffer(&buf, &size);
return std::string((char*)buf, (unsigned int)size); // NOLINT
}
template<typename ThriftStruct>
bool StringToThrift(const std::string& buff,
ThriftStruct* ts) {
using namespace apache::thrift::transport; // NOLINT
using namespace apache::thrift::protocol; // NOLINT
TMemoryBuffer* buffer = new TMemoryBuffer;
buffer->write((const uint8_t*)buff.data(), buff.size());
boost::shared_ptr<TTransport> trans(buffer);
TBinaryProtocol protocol(trans);
ts->read(&protocol);
return true;
}
struct S {
// 将通常占用 2 字节:
// 3 位: b1 的值
// 2 位:不使用
// 6 位: b2 的值
// 2 位: b3 的值
// 3 位:不使用
unsigned char b1 : 3, : 2, b2 : 6, b3 : 2;
};
void tst_thrift_entry() {
OutputDbgInfo tmpOut( "tst_thrift_entry begin", "tst_thrift_entry end" ) ;
_Student__isset ttt;
std::cout << "sizeof(_Student__isset)=" << sizeof(ttt) << std::endl;
std::cout << "sizeof(testFunc)=" << sizeof(&testFunc) << std::endl;
// std::cout << "sizeof(ttt.age)=" << sizeof(ttt.age) << std::endl;
std::cout << "sizeof(S)=" << sizeof(S) << "\n"; // 通常打印 2
Student s1;
s1.__set_no(1);
s1.__set_name("Hello");
s1.__set_sex(false);
s1.__set_age(21);
// 序列化
uint8_t* buf_ptr;
uint32_t sz;
boost::shared_ptr<TMemoryBuffer> mem_buf(new TMemoryBuffer);
boost::shared_ptr<TBinaryProtocol> bin_proto(new TBinaryProtocol(mem_buf));
s1.write(bin_proto.get());
mem_buf->getBuffer(&buf_ptr, &sz);
std::string strSerial = ThriftToString< Student >( s1 );
std::cout << "strSerial=" << strSerial << std::endl;
// 反序列化
Student s2;
boost::shared_ptr<TMemoryBuffer> membuffer(new TMemoryBuffer());
boost::shared_ptr<TProtocol> protocol(new TBinaryProtocol(membuffer));
membuffer->resetBuffer(buf_ptr, sz);
s2.read(protocol.get());
printf("%d %s %d %d\n", s2.no, s2.name.c_str(), s2.sex, s2.age);
Student s_ret;
std::cout << "bret=" << StringToThrift< Student >(strSerial, &s_ret);
printf("s_ret.no=%d s_ret.name=%s s_ret.sex=%d s_ret.age=%d\n",
s_ret.no, s_ret.name.c_str(), s_ret.sex, s_ret.age);
}
很方便 thrift 内部使用该方式 参数对象序列化为字节流,包括函数调用 map 发送给对端,对端使用相同协议解开数据,调用map内对应函数+参数。
class PhotoProcessor : public ::apache::thrift::TDispatchProcessor {
protected:
boost::shared_ptr<PhotoIf> iface_;
virtual bool dispatchCall(::apache::thrift::protocol::TProtocol* iprot, ::apache::thrift::protocol::TProtocol* oprot, const std::string& fname, int32_t seqid, void* callContext);
private:
typedef void (PhotoProcessor::*ProcessFunction)(int32_t, ::apache::thrift::protocol::TProtocol*, ::apache::thrift::protocol::TProtocol*, void*);
typedef std::map<std::string, ProcessFunction> ProcessMap;
ProcessMap processMap_;
void process_SendPhoto(int32_t seqid, ::apache::thrift::protocol::TProtocol* iprot, ::apache::thrift::protocol::TProtocol* oprot, void* callContext);
public:
PhotoProcessor(boost::shared_ptr<PhotoIf> iface) :
iface_(iface) {
processMap_["SendPhoto"] = &PhotoProcessor::process_SendPhoto;
}
virtual ~PhotoProcessor() {}
};
typedef void (PhotoProcessor::*ProcessFunction)(int32_t, ::apache::thrift::protocol::TProtocol*, ::apache::thrift::protocol::TProtocol*, void*);
typedef std::map<std::string, ProcessFunction> ProcessMap;
服务器端 调用接口映射表