我正在使用 Visual Studio 2015 构建 postgres 函数,当我尝试使用我的函数时收到此消息:
server closed the connection unexpectedly This probably means the server terminated abnormally before or while processing the request.
这是我的代码:
C:
.c 文件:
#include<iostream>
#include<math.h>
extern "C" {
#include "postgres.h"
#include "fmgr.h"
#include "sysmoroundtoabnt.h"
#include "utils/builtins.h"
#include "catalog/pg_type.h"
#ifdef PG_MODULE_MAGIC
PG_MODULE_MAGIC;
#endif
}
PG_FUNCTION_INFO_V1(sysmoroundtoabnt);
Datum
sysmoroundtoabnt(PG_FUNCTION_ARGS)
{
PG_RETURN_INT32(10);
//PG_RETURN_FLOAT8(10);
//...
}
.h文件
#ifndef SYSMOROUNDTOABNT_H
#define SYSMOROUNDTOABNT_H
#include "fmgr.h"
extern "C" __declspec(dllimport) Datum sysmoroundtoabnt(PG_FUNCTION_ARGS);
#endif
Postgresql:
create or replace function teste_victor( double precision, integer )
returns double precision
as '$libdir/sysmoroundtoabnt', 'sysmoroundtoabnt' language C;
SQL命令
select teste_victor(0.015, -2)
PS:如果我更改 C 代码以返回 PG_RETURN_FLOAT8(10),我会收到此错误:
invalid memory alloc request size 4294967290
我的代码有什么问题?
最佳答案
代码
PG_RETURN_INT32(10);
注定会失败,因为该函数被声明为返回 double
而不是整数
。 C 不会原谅此类错误。
我使用正确的方法尝试了您的函数(没有 __declspec(dllimport)
,因为我在 Linux 上使用 GNU C)
PG_RETURN_FLOAT8(10);
它按预期工作。
因此,构建可执行文件时似乎一定存在错误。
如果您使用的是 C 而不是 Windows,我建议使用 PostgreSQL extension building infrastructure ,但这不是 C++ 或 Windows 上的选项。
问题是您必须使用与 PostgreSQL 相同的 #define
来构建函数。
看着definition of PG_RETURN_FLOAT8
,我怀疑有问题的 #define
是 USE_FLOAT8_BYVAL
。
您使用的 include/pg_config.h
是否与构建 PostgreSQL 时使用的相同?
如果将 /DUSE_FLOAT8_BYVAL
或 /UUSE_FLOAT8_BYVAL
添加到构建标志中,它会起作用吗?
您使用的 Visual Studio 版本是否与构建 PostgreSQL 相同?
您是使用 \MD
构建的吗?
关于Postgresql 中的 C 库函数,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/39645038/