C++ postgresql c-extension加载另一个外部库
我需要比较pHashes(phash.org)和hamming距离函数 我试过pg_相似性中的一个,但似乎不起作用。(相同相位的汉明距离不为0) 所以我想我应该使用一个c扩展来使用pHash库中的C++ postgresql c-extension加载另一个外部库,c++,c,postgresql,linker,phash,C++,C,Postgresql,Linker,Phash,我需要比较pHashes(phash.org)和hamming距离函数 我试过pg_相似性中的一个,但似乎不起作用。(相同相位的汉明距离不为0) 所以我想我应该使用一个c扩展来使用pHash库中的ph\u hamming\u distance函数 我得到的是: 相位H.c SQL 我得到的错误: ERROR: could not load library "/usr/lib/postgresql/phash.so": /usr/lib/postgresql/phash.so: undefine
ph\u hamming\u distance
函数
我得到的是:
相位H.c
SQL
我得到的错误:
ERROR: could not load library "/usr/lib/postgresql/phash.so": /usr/lib/postgresql/phash.so: undefined symbol: _Z16pg_detoast_datumP7varlena
无论如何,我一定没有正确地链接到postgresql?我仍然相信可能有更好的方法,但这就是我所做的工作 (我将添加范围检查,而不仅仅是假设所有bytea都是4字节……最终,在生产中留下一个潜在的segfault将是不好的,所以这只是一个玩具项目,这是一件好事) c-纯c文件,用gcc编译
#include <postgres.h>
#include <fmgr.h>
#include <utils/bytea.h>
#include <utils/datum.h>
//typedef unsigned __int64 ulong64;
#if defined(_MSC_VER) || defined(__BORLANDC__)
typedef unsigned __int64 ulong64;
#else
typedef unsigned long long ulong64;
#endif
extern int32 c_ph_hamming_distance (ulong64 b1, ulong64 b2);
#ifdef PG_MODULE_MAGIC
PG_MODULE_MAGIC;
#endif
PG_FUNCTION_INFO_V1(phash_hamming);
Datum phash_hamming(PG_FUNCTION_ARGS) {
bytea *bytea1 = PG_GETARG_BYTEA_P(0);
bytea *bytea2 = PG_GETARG_BYTEA_P(1);
//FIXME - length of bytea1 & bytea2 must be 4 bytes (64bits)
ulong64 long1 = *((ulong64*) bytea1);
ulong64 long2 = *((ulong64*) bytea2);
int32 ret = c_ph_hamming_distance(long1, long2);
PG_RETURN_INT32(ret);
}
SQL-相同
CREATE FUNCTION phash_hamming (bytea1 bytea, bytea2 bytea) RETURNS int AS '$libdir/phash' LANGUAGE C;
这是个老问题,但是
extern "C" {
#include <postgres.h>
#include <fmgr.h>
#ifdef PG_MODULE_MAGIC
PG_MODULE_MAGIC
#endif
}
extern“C”{
#包括
#包括
#ifdef PG_模块
PG_模块_魔术
#恩迪夫
}
抱歉,应该先谷歌,这是一个C++/C链接问题,仍然不知道解决方案。似乎是对的,因为当你需要一个PURE C应用程序(PostgreSQL)调用C++库时,你需要一些东西从C++约定到C++约定。不过,您可以将扩展函数的声明放在
extern“C”
块中,而不需要两个文件?
#include <postgres.h>
#include <fmgr.h>
#include <utils/bytea.h>
#include <utils/datum.h>
//typedef unsigned __int64 ulong64;
#if defined(_MSC_VER) || defined(__BORLANDC__)
typedef unsigned __int64 ulong64;
#else
typedef unsigned long long ulong64;
#endif
extern int32 c_ph_hamming_distance (ulong64 b1, ulong64 b2);
#ifdef PG_MODULE_MAGIC
PG_MODULE_MAGIC;
#endif
PG_FUNCTION_INFO_V1(phash_hamming);
Datum phash_hamming(PG_FUNCTION_ARGS) {
bytea *bytea1 = PG_GETARG_BYTEA_P(0);
bytea *bytea2 = PG_GETARG_BYTEA_P(1);
//FIXME - length of bytea1 & bytea2 must be 4 bytes (64bits)
ulong64 long1 = *((ulong64*) bytea1);
ulong64 long2 = *((ulong64*) bytea2);
int32 ret = c_ph_hamming_distance(long1, long2);
PG_RETURN_INT32(ret);
}
#include <pHash.h>
extern "C" {
int c_ph_hamming_distance (ulong64 b1, ulong64 b2){
return ph_hamming_distance(b1, b2);
}
}
CFLAGS=-I/usr/include/postgresql/server
LDFLAGS=-lpHash
all: phash.so
phash_wrapper.o: phash_wrapper.cpp
$(CXX) $(CXXFLAGS) -fpic -c phash_wrapper.cpp
phash.o: phash.c
$(CC) $(CFLAGS) -fpic -c phash.c
phash.so: phash.o phash_wrapper.o
$(CC) $(LDFLAGS) -shared -o phash.so phash.o phash_wrapper.o
install:
cp phash.so `pg_config --pkglibdir`
clean:
rm -f phash.o phash.so phash_wrapper.o
CREATE FUNCTION phash_hamming (bytea1 bytea, bytea2 bytea) RETURNS int AS '$libdir/phash' LANGUAGE C;
extern "C" {
#include <postgres.h>
#include <fmgr.h>
#ifdef PG_MODULE_MAGIC
PG_MODULE_MAGIC
#endif
}