Skip site navigation (1) Skip section navigation (2)

Re: could not load library; undefined symbol: itoa

From: Alexey Klyukin <alexk(at)commandprompt(dot)com>
To: bence(at)net(dot)info(dot)hu
Cc: pgeu-general(at)postgresql(dot)org
Subject: Re: could not load library; undefined symbol: itoa
Date: 2009-04-21 10:51:30
Message-ID: 2E61BE2E-8192-45ED-A7BF-31F1CCC83641@commandprompt.com (view raw or flat)
Thread:
Lists: pgeu-general
On Apr 21, 2009, at 12:08 PM, bence(at)net(dot)info(dot)hu wrote:

> Hi!
>
> I' have tried to add a C language function called 'djb_hash' to my  
> databse.
> It accepts a 32 chars length text as input, and returns a ten chars  
> length
> numeric string.
> It implements the 'djb_hash' string hash algorithm, wich  
> unfortunetly returns
> unsigned int type, so a I had to write it as a C language function.  
> So I
> had to convert the return value to text. I used to compile it with  
> MinGW
> and used it on Windows, but now I'd like to use on Linux (Ubuntu 9.04,
> PostgreSQL 8.3).

Hm.. you can use a built-in bigint datatype if integer range is not  
sufficient for you. Of course C would give you a faster implementation  
then pl/pgsql or any other pl language, but it is a more complex one.


> When I was trying to compile, I ran into numerous errors that  
> concerned
> type definitions in the headrs (postgres.h, fmgr.h, c.h). The point is
> I have changed the 'varlena' definition in the 'c.h' (the vl_len_ is  
> now
> int)

I think this is the wrong way to deal with that errors. You shouldn't  
modify postgres headers for the addon function.

> Now I have successfully complied, but I can't add it because it
> complains about:
>
> undefined symbol: itoa
>

itoa is a non-standard function and AFAIK is missing in glibc. Use  
sprintf instead.


> Here is the definition of the function:
> #include <math.h>
> #include <string.h>
> #include "/usr/include/postgresql/8.3/server/postgres.h"
> #include "/usr/include/postgresql/8.3/server/fmgr.h"

The latest 2 should be

#include "postgres.h"
#include "fmgr.h"

before including all other files. I recommend you either use -I/path/ 
to/server/includes or use PGXS as described here:
http://www.postgresql.org/docs/8.3/interactive/xfunc-c.html#DFUNC

Also, you shouldn't deal with varlena attributes, like vl_len_  
directly. Instead, use textin to convert you result from char * to the  
text type on exit, i.e with the following macro:

#define GET_TEXT(cstrp) DatumGetTextP(DirectFunctionCall1(textin,  
CStringGetDatum(cstrp)))
It will return the value of text * for you.

>
>
> #ifdef PG_MODULE_MAGIC
> PG_MODULE_MAGIC;
> #endif
>
> PG_FUNCTION_INFO_V1(djb_hash);
> Datum
> djb_hash(PG_FUNCTION_ARGS)
> {
> 	char buffer[32];
> 	char output[11];
> 	char* str;
> 	text *szoveg = PG_GETARG_TEXT_P(0);
> 	text *hash_text = (text*) palloc(VARHDRSZ+10);
> 	hash_text->vl_len_ = VARHDRSZ+10;
>
>
> 	unsigned int hash = 5381;
> 	unsigned int i = 0;
> 	unsigned int number = 0;
>
>
> 	memcpy(buffer,szoveg->vl_dat,32);
> 	str = &buffer[0];
>
>
> 	for(i=0; i<32; str++, i++)
> 	{
> 	   hash = ((hash << 5) + hash) + (*str);
> 	}
>
> 	str = &output[0];
> 	number = hash/pow(10,9);
>
> 	if(number != 0)
> 	{
> 		hash = hash - number*pow(10,9);
> 		(*str) = '0'+ number;
> 	}
> 	else
> 	(*str)='0';
>
> 	str++;
>
> 	for(i=8;str;str++,i--)
> 	{
> 		number = 0;
> 		number = hash/pow(10,i);
>
> 		if (number == 0)
> 			(*str) = '0';
>
> 		else
> 		{
> 			itoa((int)hash, str, 10);
> 			break;
> 		}
> 	}
>
> 	memcpy(hash_text->vl_dat,output,10);
>
> 	PG_RETURN_TEXT_P(hash_text);
> }
>
> I probably missed something. So any idea would be helpful.
> Thanks in advance.
>

--
Alexey Klyukin       http://www.CommandPrompt.com
The PostgreSQL Company - Command Prompt, Inc.


In response to

pgeu-general by date

Next:From: Magnus HaganderDate: 2009-05-07 11:48:47
Subject: PGDay.EU 2009
Previous:From: benceDate: 2009-04-21 09:08:29
Subject: could not load library; undefined symbol: itoa

Privacy Policy | About PostgreSQL
Copyright © 1996-2014 The PostgreSQL Global Development Group