Visual C++でApache Thriftのサンプルを動かしたい
apache.orgからThrift0.9.3のソースコードをダウウンロードし、lib/cpp
の中Visual C++プロジェクトをビルドしてThriftのスタティックライブラリを作成しました。
そのライブラリを使用してThriftのサンプルを動かそうとしたのですが、リンクエラーが出てしまいビルドすることができません。
使用しているサンプルはこのサイトを参考にして書いたものです。
cpp
1#include <stdio.h> 2#include <iostream> 3 4#include <thrift/protocol/TBinaryProtocol.h> 5#include <thrift/transport/TSocket.h> 6#include <thrift/transport/TTransportUtils.h> 7 8#include "../gen-cpp/TinyCalc.h" 9 10using namespace std; 11using namespace apache::thrift; 12using namespace apache::thrift::protocol; 13using namespace apache::thrift::transport; 14 15using namespace boost; 16 17int main() { 18 boost::shared_ptr<TTransport> socket(new TSocket("localhost", 9090)); 19 boost::shared_ptr<TTransport> transport(new TBufferedTransport(socket)); 20 boost::shared_ptr<TProtocol> protocol(new TBinaryProtocol(transport)); 21 TinyCalcClient client(protocol); 22 23 try { 24 transport->open(); 25 26 double sum = client.sum(1.0, 1.0); 27 std::cout << "1 + 1 = " << sum << std::endl; 28 29 transport->close(); 30 } 31 catch (TException &tx) { 32 std::cout << "ERROR: " << &tx << std::endl; 33 } 34}
thrift
1# TinyCalc.thrift 2 3service TinyCalc 4{ 5 double sum(1: double param1, 2: double param2) 6 double subtract(1:double param1, 2:double param2) 7 double fact(1: i32 param1) 8}
試したこと
libthrift.libとそのヘッダファイルは参照されている。
追加のインクルードディレクトリはヘッダファイルが置いてあるディレクトリを参照している
src以下はこのような感じにディレクトリがある
Client.cppには特に赤波線のエラーは出ていない
libファイルはDebug/Releaseで分けてある
上図のReleaseディレクトリの中身
エラー内容
開発環境
Visual Studio 2017 Community
追記
cpp
1//TinyCalc.h 2ifndef TinyCalc_H 3#define TinyCalc_H 4 5#include <thrift/TDispatchProcessor.h> 6#include <thrift/async/TConcurrentClientSyncInfo.h> 7#include "TinyCalc_types.h" 8 9 10 11#ifdef _WIN32 12 #pragma warning( push ) 13 #pragma warning (disable : 4250 ) //inheriting methods via dominance 14#endif 15 16class TinyCalcIf { 17 public: 18 virtual ~TinyCalcIf() {} 19 virtual double sum(const double param1, const double param2) = 0; 20 virtual double subtract(const double param1, const double param2) = 0; 21}; 22 23 24.... 25
TinyCalc_types.hは必要な値を入れていないので使われません
これらのコードはthriftで自動的に作成されるコードです。
TinyCalcの部分をコメントアウトしたものがこちらです
cpp
1#include <stdio.h> 2#include <iostream> 3 4#include <thrift/protocol/TBinaryProtocol.h> 5#include <thrift/transport/TSocket.h> 6#include <thrift/transport/TTransportUtils.h> 7 8//#include "../gen-cpp/TinyCalc.h" 9 10 11using namespace std; 12using namespace apache::thrift; 13using namespace apache::thrift::transport; 14using namespace apache::thrift::protocol; 15 16using namespace boost; 17 18int main() { 19 boost::shared_ptr<TTransport> socket(new TSocket("localhost", 9090)); 20 boost::shared_ptr<TTransport> transport(new TBufferedTransport(socket)); 21 boost::shared_ptr<TProtocol> protocol(new TBinaryProtocol(transport)); 22 /* 23 TinyCalcClient client(protocol); 24 25 try { 26 transport->open(); 27 28 double sum = client.sum(1.0, 1.0); 29 std::cout << "1 + 1 = " << sum << std::endl; 30 31 transport->close(); 32 } 33 catch (TException &tx) { 34 std::cout << "ERROR: " << &tx << std::endl; 35 }*/ 36 37 return 0; 38}
thriftとboostしか使用していませんが、リンクエラーが出ます。
boostはNugetからインストール済みです。
エラー内容はこちらです。
これらのソースはgithubにアップロードしてあります
2017 11/2 15:14 追記
使用するThriftをThrift0.9.3ではなく最新のThrift0.10.0に変えて、TProtocol.cppをプロジェクトに追加
そのlibを対象のプロジェクトで参照したところ、Thriftのみのソースではビルドができました。↓
cpp
1#include <thrift/protocol/TBinaryProtocol.h> 2#include <thrift/transport/TSocket.h> 3#include <thrift/transport/TTransportUtils.h> 4 5using namespace std; 6using namespace apache::thrift; 7using namespace apache::thrift::transport; 8using namespace apache::thrift::protocol; 9 10using namespace boost; 11 12int main() { 13 boost::shared_ptr<TTransport> socket(new TSocket("localhost", 9090)); 14 15 return 0; 16}
この時、Nugetからインストールされてるはずのboostが何故か参照されないエラーが発生したので、Nugetからでなく自分でビルドしたboostを使用したところ、エラーを吐かなくなりました。
thriftでコンパイルしたTinyCalcをビルドしてみろという指摘があったのでスタティックライブラリとしてビルドした後、libthrift.libと同じように参照し以下のソースを書いてビルドしてみました
cpp
1#include <stdio.h> 2#include <iostream> 3 4#include <thrift/protocol/TBinaryProtocol.h> 5#include <thrift/transport/TSocket.h> 6#include <thrift/transport/TTransport.h> 7#include <thrift/transport/TTransportUtils.h> 8 9#include <TinyCalc.h> 10 11using namespace std; 12using namespace apache::thrift; 13using namespace apache::thrift::protocol; 14using namespace apache::thrift::transport; 15 16using namespace boost; 17 18int main() { 19 boost::shared_ptr<TTransport> socket(new TSocket("localhost", 9090)); 20 boost::shared_ptr<TTransport> transport(new TBufferedTransport(socket)); 21 boost::shared_ptr<TProtocol> protocol(new TBinaryProtocol(transport)); 22 TinyCalcClient client(protocol); 23 24 try { 25 transport->open(); 26 27 double sum = client.sum(1.0, 1.0); 28 std::cout << "1 + 1 = " << sum << std::endl; 29 30 transport->close(); 31 } 32 catch (TException &tx) { 33 std::cout << "ERROR: " << &tx << std::endl; 34 } 35}
すると、今度はSSLSocketでリンクエラーが発生しました。
このSSLSocketは使う機会がほとんどなく、別のものに依存しないので、ThriftのプロジェクトからSSLSocketのみを外してビルドし、そのlibを使って上記のコードをビルドしたところ、リンクエラーが発生することもなくビルドが成功しました。
Thriftのクライアント側のビルドが成功したのでサーバ側のソースを同じ環境でビルドしたのですが、そちら側は失敗してしまいました。
サーバ側のソースコードはこちらです
cpp
1#include <TinyCalc.h> 2#include <thrift/protocol/TBinaryProtocol.h> 3#include <thrift/server/TSimpleServer.h> 4#include <thrift/transport/TServerSocket.h> 5#include <thrift/transport/TBufferTransports.h> 6 7using namespace ::apache::thrift; 8using namespace ::apache::thrift::protocol; 9using namespace ::apache::thrift::transport; 10using namespace ::apache::thrift::server; 11 12using boost::shared_ptr; 13 14class TinyCalcHandler : virtual public TinyCalcIf { 15 public: 16 TinyCalcHandler() { 17 // Your initialization goes here 18 } 19 20 double sum(const double param1, const double param2) { 21 // Your implementation goes here 22 printf("sum\n"); 23 24 return param1 + param2; 25 } 26 27 double subtract(const double param1, const double param2) { 28 // Your implementation goes here 29 printf("subtract\n"); 30 31 return param1 - param2; 32 } 33 34}; 35 36int main(int argc, char **argv) { 37 int port = 9090; 38 shared_ptr<TinyCalcHandler> handler(new TinyCalcHandler()); 39 shared_ptr<TProcessor> processor(new TinyCalcProcessor(handler)); 40 shared_ptr<TServerTransport> serverTransport(new TServerSocket(port)); 41 shared_ptr<TTransportFactory> transportFactory(new TBufferedTransportFactory()); 42 shared_ptr<TProtocolFactory> protocolFactory(new TBinaryProtocolFactory()); 43 44 TSimpleServer server(processor, serverTransport, transportFactory, protocolFactory); 45 server.serve(); 46 return 0; 47}
回答2件
あなたの回答
tips
プレビュー