LoginSignup
3
1

More than 3 years have passed since last update.

ThriftをC言語で使ってみる

Posted at

この記事について

C言語でThriftを使いたいと思ったのですが、結構面倒だったので備忘録&情報共有のため投稿します。

なぜThrift?

C++だけでなくC言語にも対応しているからです。
最近がgRPC(Protocol Buffers)の方が勢いがある気もしますが、今回はThriftを使ってみます。

前提

dockerとThriftの知識が少し必要です。
dockerに関しては、dockerイメージの部分を純粋なCentOSと読み替えれば大丈夫です。
この記事で使用するソース等はここに配置していますので参考にしてください。

なぜC言語?

筆者はここ20年くらい、Java中心の仕事をしていますが久しぶりにC言語が使いたくなったのです。そしてこれがやりたい!

スクリーンショット 2019-05-12 23.00.03.png

Berkeley DBのフル機能を使うためにはJava EditionではなくC言語版が必要でした。
そして、最終的これやってみたい。
スクリーンショット 2019-05-19 14.40.48.png

やるとは言ってません。やってみたいだけです。

開発環境の準備

C言語やC++を使う時に一番面倒なのはこれです。
多くの依存モジュールをインストールする必要があります。

以前はMacに直接環境を作っていましたが、今はContainerが便利ですね。
CentOSのDockerイメージで環境を作ります。もちろん純粋なCentOSでも構いません。

docker run -it -d --name="mycentos" centos /bin/bash
docker attach mycentos

基本的に、Thriftのマニュアル(https://thrift.apache.org/docs/install/centos)通りにインストールすればよいのですが、C言語で動作させる場合は少し追加が必要です。
以下に追加の環境設定手順を記載します。
同じことを行っているDockerfileもご活用ください。

不足モジュールのインストール

※テストを簡単に行うため、Pythonも使えるようにしておきます。

#Install glib2
yum -y install glib2-devel

#Install Pip(Pythonを使う場合)
wget https://thrift.apache.org/docs/install/centos
python get-pip.py
python -m pip -V

#Install six (Python modules)
pip install six

ビルド時にpythonとc_glibのライブラリが使えるよに指定します。

#Build and Install Thrift Compiler
git clone https://github.com/apache/thrift.git
cd thrift
RUN ./bootstrap.sh
RUN ./configure --with-lua=no --with-python=yes --with-c_glib=yes 
RUN make
RUN make install

ライブラリパスも忘れずに!

export LD_LIBRARY_PATH=/usr/local/bin

サンプルコード

ping() と hello() のインターフェースを実装します。
Thrift公式ページのTutorial(https://thrift.apache.org/tutorial)を参考にしていますが、もっとシンプルにしました。
ソースはこちら

インターフェースはsample.thriftに定義する必要があります。
仕様はこちら

sample.thrift
namespace c_glib  sample 
namespace py sample

# hello              :Sample implementation
service Basic
{
      void ping(), 
      string hello(1:string arg)
}

サーバ側の実装

サンプル3.png

|-- Makefile
|-- sample.thrift
|-- server.c

スケルトンの生成

  • まず、I/Fが定義されているsample.thriftをThriftコンパイラでコンパイルし、必要なスケルトンソースを生成します。
thrift --gen c_glib sample.thrift

gen-c_glibディレクトリが作成されています。

|-- Makefile
|-- sample.thrift
|-- server.c
|-- gen-c_glib
|   |-- sample_basic.c
|   |-- sample_basic.h
|   |-- sample_sample_types.c
|   `-- sample_sample_types.h

関数の実装

- 生成されたsample_basic.cに ping(),hello()の処理を記述します。

gboolean sample_basic_handler_ping (sampleBasicIf * iface, GError ** error)
{
  /* TODO: Implement your own code. */
  THRIFT_UNUSED_VAR (iface);
  THRIFT_UNUSED_VAR (error);
  puts ("ping()");
  return TRUE;
}

gboolean sample_basic_handler_hello (sampleBasicIf * iface, gchar ** _return, const gchar * arg, GError ** error)
{
  /* TODO: Implement your own code. */
  THRIFT_UNUSED_VAR (iface);
  THRIFT_UNUSED_VAR (error);
  GString *retValue;
  retValue = g_string_new( NULL );
  g_string_printf( retValue ,"Server received: %s \n" , arg );
  puts( retValue->str );
  *_return = retValue->str;
  return TRUE; 
}

サーバ実行

dockerイメージで実行してみます
/root/dev/c_thrift_sample の下にソースがあることを想定しています

docker run -it mycentos /bin/bash
# cd /root/dev/c_thrift_sample
# make idl (or #thrift --gen c_glib sample.thrift)
# make 
# ./server
Starting the server...

9090ポートでListenしています

クライアント側

クライアントのコードはpythonで記述します。
サンプル4.png

クライアント実装

ソースコードはこちら

client.py
print "Call ping() = %s " % (client.ping(),)
print "Call hello() = %s " % (client.hello("Hey guys!"),)

必要なPythonモジュールの生成

thrift --gen py sample.thrift  #<--- C言語のスケルトン生成時に使用したファイル

クライアント実行

docker exec -it 232db73154c2  /bin/bash  #<---  232db73154c2 はサーバ動作中のCONTAINER IDです
# cd /root/dev/c_thrift_sample/test/python  #<---  テストコードはここにある想定
# python client.py
Call ping() = None
Call hello() = Server received: Hey guys!

pythonクライアントから送った文字列がC言語で作成したサーバで受信できました。

おまけ

thriftコンパイラで生成したソースを変更しましたが、もう一度生成すると、上書きされて消えてしまいます。
そこで、変更したhandler関数を外出ししました。
ソース類をここに置きます。興味のある方はご覧ください。

まとめ

今更ですがC言語は難しい!
BerkeleyDBも少し使ってみたのですが、久しぶりに使ってみて痛感しました。
最近の言語では、あまり意識する必要がない「メモリ管理」や「UNICODE文字列の操作」などを、自分で作るか外部ライブラリに頼ることになります。
モジュールやライブラリの管理も微妙で難易度がさらに上がります。
しかし、C言語はとてもシンプルなので、性能や実行モジュールサイズはC言語に敵うものはありません。
これからも職人のツールとして残るでしょう。
最後に
 C言語は計算機の仕組みを理解するには一番良い言語です
 これを理解していれば、新しい言語や技術に対応できる能力が身につきます
筆者のようなおじさんだけでなく、若い技術者にもトライしてほしいと思います

3
1
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
3
1