在 Windows 中编译 Apache Thrift 服务
我正在尝试在我的 Windows 机器上构建一个 Thrift 服务。我使用 cygwin 和 Netbeans IDE。我已经下载了 Thrift 并通过 cygwin 构建了它,并且能够成功让 Thrift 为我生成服务器代码,如下所示。
#include "Feed.h"
#include <protocol/TBinaryProtocol.h>
#include <server/TSimpleServer.h>
#include <transport/TServerSocket.h>
#include <transport/TBufferTransports.h>
using namespace ::apache::thrift;
using namespace ::apache::thrift::protocol;
using namespace ::apache::thrift::transport;
using namespace ::apache::thrift::server;
using boost::shared_ptr;
using namespace feed;
class FeedHandler : virtual public FeedIf {
public:
FeedHandler() {
// Your initialization goes here
}
void ping() {
// Your implementation goes here
printf("ping\n");
}
void search_text(search_resultset& _return, const std::string& query, const int32_t offset, const int32_t per_page) {
// Your implementation goes here
printf("search_text\n");
}
void search_prox_web(search_resultset& _return, const double lat, const double lon, const int32_t offset, const int32_t distance) {
// Your implementation goes here
printf("search_prox_web\n");
}
void search_prox_mob(search_resultset& _return, const double lat, const double lon, const int32_t offset, const int32_t distance) {
// Your implementation goes here
printf("search_prox_mob\n");
}
int32_t add_event(const std::string& name) {
// Your implementation goes here
printf("add_event\n");
}
int32_t associate_venue_with_event(const int32_t event_id, const int32_t venue_id, const int32_t usr_loc_id) {
// Your implementation goes here
printf("associate_venue_with_event\n");
}
int32_t save_usr_loc(const std::string& address) {
// Your implementation goes here
printf("save_usr_loc\n");
}
};
int main(int argc, char **argv) {
int port = 9090;
shared_ptr<FeedHandler> handler(new FeedHandler());
shared_ptr<TProcessor> processor(new FeedProcessor(handler));
shared_ptr<TServerTransport> serverTransport(new TServerSocket(port));
shared_ptr<TTransportFactory> transportFactory(new TBufferedTransportFactory());
shared_ptr<TProtocolFactory> protocolFactory(new TBinaryProtocolFactory());
TSimpleServer server(processor, serverTransport, transportFactory, protocolFactory);
server.serve();
return 0;
}
然后我构建了库,以便可以编译和链接我的实现。库构建成功,但是当我尝试编译时,出现以下错误:
build/Debug/Cygwin_4.x-Windows/main.o: In function `FeedProcessor':
/cygdrive/c/Feed Service/Feed.h:930: undefined reference to `vtable for feed::FeedProcessor'
/cygdrive/c/Feed Service/Feed.h:930: undefined reference to `vtable for feed::FeedProcessor'
/cygdrive/c/Feed Service/Feed.h:931: undefined reference to `feed::FeedProcessor::process_ping(int, apache::thrift::protocol::TProtocol*, apache::thrift::protocol::TProtocol*, void*)'
/cygdrive/c/Feed Service/Feed.h:932: undefined reference to `feed::FeedProcessor::process_search_text(int, apache::thrift::protocol::TProtocol*, apache::thrift::protocol::TProtocol*, void*)'
/cygdrive/c/Feed Service/Feed.h:933: undefined reference to `feed::FeedProcessor::process_search_prox_web(int, apache::thrift::protocol::TProtocol*, apache::thrift::protocol::TProtocol*, void*)'
/cygdrive/c/Feed Service/Feed.h:934: undefined reference to `feed::FeedProcessor::process_search_prox_mob(int, apache::thrift::protocol::TProtocol*, apache::thrift::protocol::TProtocol*, void*)'
/cygdrive/c/Feed Service/Feed.h:935: undefined reference to `feed::FeedProcessor::process_add_event(int, apache::thrift::protocol::TProtocol*, apache::thrift::protocol::TProtocol*, void*)'
/cygdrive/c/Feed Service/Feed.h:936: undefined reference to `feed::FeedProcessor::process_associate_venue_with_event(int, apache::thrift::protocol::TProtocol*, apache::thrift::protocol::TProtocol*, void*)'
/cygdrive/c/Feed Service/Feed.h:937: undefined reference to `feed::FeedProcessor::process_save_usr_loc(int, apache::thrift::protocol::TProtocol*, apache::thrift::protocol::TProtocol*, void*)'
collect2: ld returned 1 exit status
make[2]: *** [dist/Debug/Cygwin_4.x-Windows/feed_service.exe] Error 1
make[1]: *** [.build-conf] Error 2
make: *** [.build-impl] Error 2
BUILD FAILED (exit value 2, total time: 3s)
我认为这些都是链接器错误,因此我进行了一些谷歌搜索,找到了一个潜在的解决方案,将以下行添加到 makefile:
THRIFT_O=C:/cygwin/home/thrift/lib/cpp
LTHRIFT=$(THRIFT_O)/Thrift.o $(THRIFT_O)/TSocket.o $(THRIFT_O)/TSimpleServer.o $(THRIFT_O)/TBufferTransports.o $(THRIFT_O)/TSimpleServer.o $(THRIFT_O)/TBinaryProtocol.o
然后使用 $( 链接LTHRIFT) 而不是 -lthrift。但是,文件 TBinaryProtocol.o 在我的系统上似乎不存在。我尝试从源代码重新构建库两次,但文件仍然没有创建。
首先,将这些行添加到我的 makefile 中是解决我最初问题的正确方法吗?其次,缺少 TBinaryProtocol.oa 是主要问题,还是因为某种原因而没有创建它?如果我确实需要它,有没有办法可以单独制作或从某处下载?
编辑:所有包含文件都是由 Thrift 编译器自动生成的。我尝试在此处包含 Feed.h,但它太大并且超出了字符限制,因此我包含了错误中引用的部分。
class FeedProcessor : virtual public ::apache::thrift::TProcessor {
protected:
boost::shared_ptr<FeedIf> iface_;
virtual bool process_fn(::apache::thrift::protocol::TProtocol* iprot, ::apache::thrift::protocol::TProtocol* oprot, std::string& fname, int32_t seqid, void* callContext);
private:
std::map<std::string, void (FeedProcessor::*)(int32_t, ::apache::thrift::protocol::TProtocol*, ::apache::thrift::protocol::TProtocol*, void*)> processMap_;
void process_ping(int32_t seqid, ::apache::thrift::protocol::TProtocol* iprot, ::apache::thrift::protocol::TProtocol* oprot, void* callContext);
void process_search_text(int32_t seqid, ::apache::thrift::protocol::TProtocol* iprot, ::apache::thrift::protocol::TProtocol* oprot, void* callContext);
void process_search_prox_web(int32_t seqid, ::apache::thrift::protocol::TProtocol* iprot, ::apache::thrift::protocol::TProtocol* oprot, void* callContext);
void process_search_prox_mob(int32_t seqid, ::apache::thrift::protocol::TProtocol* iprot, ::apache::thrift::protocol::TProtocol* oprot, void* callContext);
void process_add_event(int32_t seqid, ::apache::thrift::protocol::TProtocol* iprot, ::apache::thrift::protocol::TProtocol* oprot, void* callContext);
void process_associate_venue_with_event(int32_t seqid, ::apache::thrift::protocol::TProtocol* iprot, ::apache::thrift::protocol::TProtocol* oprot, void* callContext);
void process_save_usr_loc(int32_t seqid, ::apache::thrift::protocol::TProtocol* iprot, ::apache::thrift::protocol::TProtocol* oprot, void* callContext);
public:
FeedProcessor(boost::shared_ptr<FeedIf> iface) :
iface_(iface) {
processMap_["ping"] = &FeedProcessor::process_ping;
processMap_["search_text"] = &FeedProcessor::process_search_text;
processMap_["search_prox_web"] = &FeedProcessor::process_search_prox_web;
processMap_["search_prox_mob"] = &FeedProcessor::process_search_prox_mob;
processMap_["add_event"] = &FeedProcessor::process_add_event;
processMap_["associate_venue_with_event"] = &FeedProcessor::process_associate_venue_with_event;
processMap_["save_usr_loc"] = &FeedProcessor::process_save_usr_loc;
}
virtual bool process(boost::shared_ptr< ::apache::thrift::protocol::TProtocol> piprot, boost::shared_ptr< ::apache::thrift::protocol::TProtocol> poprot, void* callContext);
virtual ~FeedProcessor() {}
};
任何帮助将不胜感激,我对此非常坚持。
I'm trying to build a thrift service on my windows machine. Im using cygwin and Netbeans IDE. I've downloaded Thrift and built it trough cygwin and was able to successfully get Thrift to generate the server code for me, shown below.
#include "Feed.h"
#include <protocol/TBinaryProtocol.h>
#include <server/TSimpleServer.h>
#include <transport/TServerSocket.h>
#include <transport/TBufferTransports.h>
using namespace ::apache::thrift;
using namespace ::apache::thrift::protocol;
using namespace ::apache::thrift::transport;
using namespace ::apache::thrift::server;
using boost::shared_ptr;
using namespace feed;
class FeedHandler : virtual public FeedIf {
public:
FeedHandler() {
// Your initialization goes here
}
void ping() {
// Your implementation goes here
printf("ping\n");
}
void search_text(search_resultset& _return, const std::string& query, const int32_t offset, const int32_t per_page) {
// Your implementation goes here
printf("search_text\n");
}
void search_prox_web(search_resultset& _return, const double lat, const double lon, const int32_t offset, const int32_t distance) {
// Your implementation goes here
printf("search_prox_web\n");
}
void search_prox_mob(search_resultset& _return, const double lat, const double lon, const int32_t offset, const int32_t distance) {
// Your implementation goes here
printf("search_prox_mob\n");
}
int32_t add_event(const std::string& name) {
// Your implementation goes here
printf("add_event\n");
}
int32_t associate_venue_with_event(const int32_t event_id, const int32_t venue_id, const int32_t usr_loc_id) {
// Your implementation goes here
printf("associate_venue_with_event\n");
}
int32_t save_usr_loc(const std::string& address) {
// Your implementation goes here
printf("save_usr_loc\n");
}
};
int main(int argc, char **argv) {
int port = 9090;
shared_ptr<FeedHandler> handler(new FeedHandler());
shared_ptr<TProcessor> processor(new FeedProcessor(handler));
shared_ptr<TServerTransport> serverTransport(new TServerSocket(port));
shared_ptr<TTransportFactory> transportFactory(new TBufferedTransportFactory());
shared_ptr<TProtocolFactory> protocolFactory(new TBinaryProtocolFactory());
TSimpleServer server(processor, serverTransport, transportFactory, protocolFactory);
server.serve();
return 0;
}
Then I built the libraries so I could compile and link my implementation. The libraries built successfully, however when I try to compile I get the following error:
build/Debug/Cygwin_4.x-Windows/main.o: In function `FeedProcessor':
/cygdrive/c/Feed Service/Feed.h:930: undefined reference to `vtable for feed::FeedProcessor'
/cygdrive/c/Feed Service/Feed.h:930: undefined reference to `vtable for feed::FeedProcessor'
/cygdrive/c/Feed Service/Feed.h:931: undefined reference to `feed::FeedProcessor::process_ping(int, apache::thrift::protocol::TProtocol*, apache::thrift::protocol::TProtocol*, void*)'
/cygdrive/c/Feed Service/Feed.h:932: undefined reference to `feed::FeedProcessor::process_search_text(int, apache::thrift::protocol::TProtocol*, apache::thrift::protocol::TProtocol*, void*)'
/cygdrive/c/Feed Service/Feed.h:933: undefined reference to `feed::FeedProcessor::process_search_prox_web(int, apache::thrift::protocol::TProtocol*, apache::thrift::protocol::TProtocol*, void*)'
/cygdrive/c/Feed Service/Feed.h:934: undefined reference to `feed::FeedProcessor::process_search_prox_mob(int, apache::thrift::protocol::TProtocol*, apache::thrift::protocol::TProtocol*, void*)'
/cygdrive/c/Feed Service/Feed.h:935: undefined reference to `feed::FeedProcessor::process_add_event(int, apache::thrift::protocol::TProtocol*, apache::thrift::protocol::TProtocol*, void*)'
/cygdrive/c/Feed Service/Feed.h:936: undefined reference to `feed::FeedProcessor::process_associate_venue_with_event(int, apache::thrift::protocol::TProtocol*, apache::thrift::protocol::TProtocol*, void*)'
/cygdrive/c/Feed Service/Feed.h:937: undefined reference to `feed::FeedProcessor::process_save_usr_loc(int, apache::thrift::protocol::TProtocol*, apache::thrift::protocol::TProtocol*, void*)'
collect2: ld returned 1 exit status
make[2]: *** [dist/Debug/Cygwin_4.x-Windows/feed_service.exe] Error 1
make[1]: *** [.build-conf] Error 2
make: *** [.build-impl] Error 2
BUILD FAILED (exit value 2, total time: 3s)
I thought these were all linker errors, so I did some googling and found a potential solution to add the following lines to the makefile:
THRIFT_O=C:/cygwin/home/thrift/lib/cpp
LTHRIFT=$(THRIFT_O)/Thrift.o $(THRIFT_O)/TSocket.o $(THRIFT_O)/TSimpleServer.o $(THRIFT_O)/TBufferTransports.o $(THRIFT_O)/TSimpleServer.o $(THRIFT_O)/TBinaryProtocol.o
and then link with $(LTHRIFT) rather than -lthrift. However the file TBinaryProtocol.o doesn't seem to exist on my system. I tried re-building the libraries from source twice, and the file still isn't made.
First of all, is adding these lines to my makefile the correct solution to my initial problem? Secondly, is the absence of TBinaryProtocol.o a major problem, or is it not created for a reason? If I do need it, is there a way I can make it individually or download it from somewhere?
Edit: All of the include files are auto-generated by the Thrift compiler. I tried to include Feed.h here, but it is too big and goes over the character limit, so I included the portion that is referenced in the errors.
class FeedProcessor : virtual public ::apache::thrift::TProcessor {
protected:
boost::shared_ptr<FeedIf> iface_;
virtual bool process_fn(::apache::thrift::protocol::TProtocol* iprot, ::apache::thrift::protocol::TProtocol* oprot, std::string& fname, int32_t seqid, void* callContext);
private:
std::map<std::string, void (FeedProcessor::*)(int32_t, ::apache::thrift::protocol::TProtocol*, ::apache::thrift::protocol::TProtocol*, void*)> processMap_;
void process_ping(int32_t seqid, ::apache::thrift::protocol::TProtocol* iprot, ::apache::thrift::protocol::TProtocol* oprot, void* callContext);
void process_search_text(int32_t seqid, ::apache::thrift::protocol::TProtocol* iprot, ::apache::thrift::protocol::TProtocol* oprot, void* callContext);
void process_search_prox_web(int32_t seqid, ::apache::thrift::protocol::TProtocol* iprot, ::apache::thrift::protocol::TProtocol* oprot, void* callContext);
void process_search_prox_mob(int32_t seqid, ::apache::thrift::protocol::TProtocol* iprot, ::apache::thrift::protocol::TProtocol* oprot, void* callContext);
void process_add_event(int32_t seqid, ::apache::thrift::protocol::TProtocol* iprot, ::apache::thrift::protocol::TProtocol* oprot, void* callContext);
void process_associate_venue_with_event(int32_t seqid, ::apache::thrift::protocol::TProtocol* iprot, ::apache::thrift::protocol::TProtocol* oprot, void* callContext);
void process_save_usr_loc(int32_t seqid, ::apache::thrift::protocol::TProtocol* iprot, ::apache::thrift::protocol::TProtocol* oprot, void* callContext);
public:
FeedProcessor(boost::shared_ptr<FeedIf> iface) :
iface_(iface) {
processMap_["ping"] = &FeedProcessor::process_ping;
processMap_["search_text"] = &FeedProcessor::process_search_text;
processMap_["search_prox_web"] = &FeedProcessor::process_search_prox_web;
processMap_["search_prox_mob"] = &FeedProcessor::process_search_prox_mob;
processMap_["add_event"] = &FeedProcessor::process_add_event;
processMap_["associate_venue_with_event"] = &FeedProcessor::process_associate_venue_with_event;
processMap_["save_usr_loc"] = &FeedProcessor::process_save_usr_loc;
}
virtual bool process(boost::shared_ptr< ::apache::thrift::protocol::TProtocol> piprot, boost::shared_ptr< ::apache::thrift::protocol::TProtocol> poprot, void* callContext);
virtual ~FeedProcessor() {}
};
Any help would be appreciated, I am very stuck on this.
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(1)
只是为了完整起见:
(1)在 Windows 上,无需自己构建 Thrift Compiler EXE,有一个(小)安装程序在此处下载。
(2) 如果您仍然想要或需要构建 Thrift 编译器二进制文件,您仍然不需要启动 Cygwin:较新版本的 Apache Thrift 提供了一个不错的 Visual Studio 解决方案 只需 Win flex-bison 作为依赖项。就像魅力一样。
Just for the sake of completeness:
(1) On Windows, there is no need to build the Thrift Compiler EXE on your own, there is a (small) installer to be downloaded here.
(2) If you still want or need to build the Thrift Compiler Binaries, you still don't need to fire up Cygwin: More recent versions of Apache Thrift offer a nice Visual Studio solution which only require Win flex-bison as dependency. Works like a charm.