libmemcached c++ interface

業務で libmemcached を利用した小さなモジュールを作ることになった。このライブラリにはC++インタフェースも用意されているのでCとC++の両方で試してみる。

環境は CentOS 5.6 (x86_64) , gcc4.4, libmemcached-devel

* インストール
remiレポジトリから新しいバージョンを入れる

$ sudo yum install libmemcached-devel.x86_64 --enablerepo=remi

* 各基本操作(set, get, delete)を行う C版
[cpp]
// libmemcached_test.c

#include
#include
#include
#include

int main(void) {
memcached_st *memc;
memcached_server_st *servers = NULL;
memcached_return rc;
const char* server_list = “localhost:11211”;
const char* key= “key”;
const char* value= “value”;
char* retval = NULL;
size_t len = 0;
time_t expire = 0;
uint32_t flags = 0;

// 初期化
memc = memcached_create(NULL);
servers = memcached_servers_parse(server_list);
rc = memcached_server_push(memc, servers);
memcached_server_list_free(servers); // すぐに解放してOK
if(rc == MEMCACHED_SUCCESS) {
printf(“added server successfully\n”);
} else {
printf(“couldn’t add server: %s\n”, memcached_strerror(memc, rc));
}

// set
rc = memcached_set(memc, key, strlen(key), value, strlen(value), expire, flags);
if(rc == MEMCACHED_SUCCESS) {
printf(“key stored successfully\n”);
} else {
printf(“couldn’t store key: %s\n”, memcached_strerror(memc, rc));
}

// get
retval = memcached_get(memc, key, strlen(key), &len, &flags, &rc);
if(rc == MEMCACHED_SUCCESS) {
printf(“key got successfully\n”);
printf(“value: %s\n”, retval);
} else {
printf(“couldn’t get key: %s\n”, memcached_strerror(memc, rc));
}
free(retval); // 忘れないように!!

// delete
rc = memcached_delete(memc, key, strlen(key), expire);
if(rc == MEMCACHED_SUCCESS) {
printf(“key deleted successfully\n”);
} else {
printf(“couldn’t delete key: %s\n”, memcached_strerror(memc, rc));
}

// get
retval = memcached_get(memc, key, strlen(key), &len, &flags, &rc);
if(rc == MEMCACHED_SUCCESS) {
printf(“key got successfully\n”);
printf(“value: %s\n”, retval);
} else if(rc == MEMCACHED_NOTFOUND) { // keyが存在しない
printf(“couldn’t get key (not found): %s\n”, memcached_strerror(memc, rc));
} else if(rc == MEMCACHED_FAILURE) { // memcachedに接続できない
printf(“couldn’t get key (failure): %s\n”, memcached_strerror(memc, rc));
}
free(retval);

// 解放
memcached_free(memc);
return 0;
}
[/cpp]
* コンパイル, 実行 (+ valgrindでメモリリークのチェック)

$ gcc44 -o -libmemcached_test libmemcached.c -L/usr/lib64 -lmemcached
$ valgrind ./libmemcached_test
==10510== Memcheck, a memory error detector
==10510== Copyright (C) 2002-2009, and GNU GPL'd, by Julian Seward et al.
==10510== Using Valgrind-3.5.0 and LibVEX; rerun with -h for copyright info
==10510== Command: ./libmemcached_test
==10510==
added server successfully
key stored successfully
key got successfully
value: value
key deleted successfully
couldn't get key (not found): NOT FOUND
==10510==
==10510== HEAP SUMMARY:
==10510==     in use at exit: 0 bytes in 0 blocks
==10510==   total heap usage: 54 allocs, 54 frees, 42,214 bytes allocated
==10510==
==10510== All heap blocks were freed -- no leaks are possible
==10510==
==10510== For counts of detected and suppressed errors, rerun with: -v
==10510== ERROR SUMMARY: 0 errors from 0 contexts (suppressed: 4 from 4)

memcached_get 内で malloc が行われるので free で解放するのを忘れずに。また、key が存在しない場合は NOT FOUND が、memcachedに接続出来ない場合などは FAILURE が返る。

あと、libmemcachedは関係ないけど以下のような警告が出た場合は文字列の扱いを見直す必要がある。

deprecated conversion from string constant to ‘char*’

どうやら gcc4.2 から(? 文字列の扱いに厳しくなっていて、const を付けるべき所はちゃんと付けないとだめらしい。見かけない警告だったので少し焦ったけど、そういえば会社の開発環境は gcc4.1 だったかもしれない。

次はC++インタフェースを使う。APIの使い方は libmmecached/memcached.hpp を読んで確認。

* 各基本操作(set, get, delete)を行う C++版
[cpp]
#include
// ヘッダは memcached.h ではなく memcached.hpp を include
#include

int main(void) {
using namespace std;
try {
// Memcache インスタンス生成
// 内部で memcached_create などが呼ばれて初期化処理が行われる
memcache::Memcache memc(“localhost:11211”);
string key = “mykey”;
string value_str = “myvalue”;
// value は std::string ではなく std::vector で扱う
vector value(value_str.begin(), value_str.end());
vector retval;
time_t expire = 0;
uint32_t flags = 0;

// set
// bool set(const std::string &key, const std::vector &value,
// time_t expiration, uint32_t flags)
if(memc.set(key, value, expire, flags)) {
cout<<"key stored successfully"< &ret_val)
if(memc.get(key, retval)) {
cout<<"key got successfully"<あわせて読む:

コメントを残す

メールアドレスが公開されることはありません。 が付いている欄は必須項目です