PostgreSQL C-Extension加载另一个外部库
postgresql c-extension loads another external library
我需要将 pHashes (phash.org) 与汉明距离函数进行比较。
我尝试了pg_similarity的那个,但它似乎不起作用。(相同的pHash的汉明距离不为0)。
所以我想我只需要使用 c 扩展来使用 pHash 库中的 ph_hamming_distance
函数。
我得到了什么:帕什.c
#include <postgres.h>
#include <pHash.h>
#include <fmgr.h>
#include <utils/bytea.h>
#include <utils/datum.h>
#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 = ph_hamming_distance(long1, long2);
PG_RETURN_INT32(ret);
}
生成文件
CXXFLAGS=-I/usr/include/postgresql/server
LDFLAGS=-Bstatic -lpHash
all: phash.o
phash.o:
$(CXX) $(CXXFLAGS) -fpic -c phash.c
$(CXX) $(LDFLAGS) -shared -o phash.so phash.o
install:
cp phash.so `pg_config --pkglibdir`
clean:
rm -f phash.o phash.so
.SQL
CREATE FUNCTION phash_hamming (bytea1 bytea, bytea2 bytea) RETURNS int AS '$libdir/phash' LANGUAGE C;
我收到的错误:
ERROR: could not load library "/usr/lib/postgresql/phash.so": /usr/lib/postgresql/phash.so: undefined symbol: _Z16pg_detoast_datumP7varlena
我一定不会以某种方式将权利链接到 postgresql?
这是一个
老问题,但是...
- 无需添加额外的包装器文件并使用 gcc 编译它。
你需要 extern "C" PostgreSQL 标头和 PostgreSQL 宏。
extern "C" { #include <postgres.h> #include <fmgr.h> #ifdef PG_MODULE_MAGIC PG_MODULE_MAGIC #endif }
我仍然相信可能有更好的方法,但这就是我所做的工作。
(我将添加范围检查,而不仅仅是假设所有bytea都是4字节...最终,在生产中留下潜在的段错误会很糟糕,所以这只是一个玩具项目是一件好事)
phash.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);
}
phash_wrapper.cpp - 使用 C 链接而不是 CPP 链接转换 ph_hamming_distance 版本(使用 G++ 编译)
#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
SQL - 相同
CREATE FUNCTION phash_hamming (bytea1 bytea, bytea2 bytea) RETURNS int AS '$libdir/phash' LANGUAGE C;
相关文章:
- 另一个类中嵌套模板的外部实例化
- 是否可以定义一个在外部"C"块中继承另一个结构的结构?
- 从另一个文件(C++,QT)访问函数未解析的外部
- 未解决的外部符号,带有静态lib,它使用了另一个静态lib
- 未解析的外部符号来自一个项目中的静态库,而不是另一个项目.(C++)
- 调用外部函数(从一个exe到另一个exe)
- PostgreSQL C-Extension加载另一个外部库
- 外部声明变量的定义适用于一个函数,但不适用于另一个函数
- 如何在另一个命名空间中使用常量定义的外部
- 视觉获取链接错误:C++中的外部.如何访问在文件 A 中修改的变量的值.CPP在另一个文件 B .CPP中修改
- 如果由另一个 OpenMP 程序调用,则外部调用的 OpenMP 程序仅使用一个线程运行
- 无法调用另一个类-ERR-未解析的外部符号
- 为什么当在另一个文件中更改外部常量时,链接器不会失败
- 实例化在另一个项目中定义的类时未解析的外部
- 另一个错误LNK2019:函数___tmainCRTStartup中引用未解析的外部符号_WinMain@16
- 来自另一个DLL的未解析的外部静态数据成员
- lambda调用另一个外部lambda
- 不能使用 Cmake 在另一个标头中包含外部库
- LNK2001:尝试从另一个 DLL 调用对象的方法时,未解析的外部符号
- 无法将一个项目的头和 CPP 文件与另一个项目链接 LNK2019:未解决的外部符号错误