坚持让Windows C版上的示例C函数正常工作

时间:2016-10-10 18:08:22

标签: windows postgresql

v9.6,赢得服务器2012,与2015年相比 已成功编译并链接为x64。

创建函数失败,说dll中没有'add_one'函数。

postgres=# create function add_one(integer) returns integer as
'win32project1',' add_one' language c strict; 

ERROR:  could not find function "add_one" in file "C:/Program Files/PostgreSQL/9.6/lib/win32project1.dll"

虽然函数似乎存在,但dumpbin说

      1    0 000112CB Pg_magic_func = @ILT+710(Pg_magic_func)
      2    1 00011087 pg_finfo_add_one = @ILT+130(pg_finfo_add_one)
      3    2 00011190 pg_finfo_add_one_float8 = @ILT+395(pg_finfo_add_one_float8)
      4    3 000110F5 pg_finfo_concat_text = @ILT+240(pg_finfo_concat_text)
      5    4 000112C1 pg_finfo_copytext = @ILT+700(pg_finfo_copytext)
      6    5 0001107D pg_finfo_makepoint = @ILT+120(pg_finfo_makepoint)

2 个答案:

答案 0 :(得分:1)

好的,每个函数需要导出2个函数,元数据函数pg_finfo_xxx加上实际函数本身xxx

pg函数编译的标准头用PGDLLEXPORT标记元数据函数,但实际函数的前向声明没有标记。我不明白这是如何工作的。

#define PG_FUNCTION_INFO_V1(funcname) \
Datum funcname(PG_FUNCTION_ARGS); \
extern PGDLLEXPORT const Pg_finfo_record * CppConcat(pg_finfo_,funcname)(void); \
const Pg_finfo_record * \
CppConcat(pg_finfo_,funcname) (void) \
{ \
    static const Pg_finfo_record my_finfo = { 1 }; \
    return &my_finfo; \
} \
extern int no_such_variable

但是我通过做

让它成功了
#define PG_FUNCTION_INFO_V1(funcname) \
PGDLLEXPORT Datum funcname(PG_FUNCTION_ARGS); \
extern PGDLLEXPORT const Pg_finfo_record * CppConcat(pg_finfo_,funcname)(void); \
const Pg_finfo_record * \
CppConcat(pg_finfo_,funcname) (void) \
{ \
    static const Pg_finfo_record my_finfo = { 1 }; \
    return &my_finfo; \
} \
extern int no_such_variable

答案 1 :(得分:0)

您没有显示源文件,但它应该包含:

0.00user 0.00system 0:00.00elapsed ?%CPU (0avgtext+0avgdata 1992maxresident)k
0inputs+0outputs (0major+85minor)pagefaults 0swaps

然后它可能会起作用。

我已经在PostgreSQL中启动了discussion on the hackes mailing list来实现your answer,但似乎在使用PostgreSQL使用的构建过程(生成并使用导出定义文件)时,这至少会引发警告,所以我们放弃了它。

你有另一个选择是创建和使用像PostgreSQL那样的导出定义文件,那么你可以完全不用PGDLLEXPORT装饰。