Question

I am trying to write a sample code using libmemcached c/c++ client version (0.53)

gcc -o test test.c -I/home/libmemcached/include -L/home/libmemcached/lib -lmemcached -lmemcachedutil

However i get an error

/tmp/ccoaToYP.o: In function main': test.c:(.text+0x255): undefined reference tomemcached_exist'

Has anyone come across this issue ? I cannot use version higher than 0.53 (basically any 1.0) due to limitation with installed gcc. I see that this command was added for 0.53.

Also, The path and ld_library_path are straightforward too. PATH is set with /bin:/sbin:/usr/bin:/usr/sbin:/usr/bin/X11:/usr/sbin. LD_LIBRARY_PATH is set with /home/libmemcached/lib:/usr/lib:/usr/lib64:/lib

$ nm libmemcached.so | grep -i memcached_exist 00014bc2 T _Z15memcached_existP12memcached_stPKcj 00014b06 T _Z22memcached_exist_by_keyP12memcached_stPKcjS2_j $

If i comment out the memcached_exist call, rest of code compiles and executes just fine.

#include <stdio.h>
#include <string.h>
#include <unistd.h>
#include <libmemcached/memcached.h>

int main(int argc, char *argv[])
{
  memcached_server_st *servers = NULL;
  memcached_st *memc;
  memcached_return rc;
  char *key= "keystring";
  char *value= "keyvalue";

  uint32_t flags;
  char return_key[MEMCACHED_MAX_KEY];
  size_t return_key_length;
  char *return_value;
  size_t return_value_length;

  memc= memcached_create(NULL);

  servers= memcached_server_list_append(servers, "localhost", 11211, &rc);
  rc= memcached_server_push(memc, servers);

  if (rc == MEMCACHED_SUCCESS)
    fprintf(stderr,"Added server successfully\n");
  else
    fprintf(stderr,"Couldn't add server: %s\n",memcached_strerror(memc, rc));

  rc= memcached_set(memc, key, strlen(key), value, strlen(value), (time_t)0, (uint32_t)0);

  if (rc == MEMCACHED_SUCCESS)
    fprintf(stderr,"Key stored successfully\n");
  else
    fprintf(stderr,"Couldn't store key: %s\n",memcached_strerror(memc, rc));

  return_value= memcached_get(memc, key, strlen(key), &return_value_length, &flags, &rc);
  if (rc == MEMCACHED_SUCCESS)
            {
              fprintf(stderr,"Key %s returned %s\n",key, return_value);
            }
  rc = memcached_exist(memc, key, strlen(key));
  fprintf(stderr," Error Code: %s\n",memcached_strerror(memc, rc));

  return 0;
}

Thanks Antony

Was it helpful?

Solution

If you don't want to compile as C++, you can always call the mangled name directly. If you want this code to be reusable and to be able to upgrade the libraries easily, etc, you shouldn't do that. For a more extensible solution, I'll add to H2CO3's answer.

If you want to for some reason keep all your main source compiled as C, you can create a .cpp file that has stubs that call the C++ library functions. For example:

// libraries.cpp
//
// (includes needed to memcached lib call and types)
extern "C" memcached_return memcached_exist(memcached_st *memc, char *key, size_t len)
{
    return memcached_exist(memc, key, len);
}

Then you can compile libraries.cpp and link against the memcached libs using g++ to a libraries.o and link against that on your gcc line.

OTHER TIPS

Name mangling. The shared object file contains mangled C++ function (method?) names, while your code is compiled as C, containing the non-mangled name memcached_exist. Try compiling your file as C++.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top