2

私は1つの関数を持つDLLを持っています

#include "postgres.h"
#include <string.h>
#include "fmgr.h"

#ifdef PG_MODULE_MAGIC
PG_MODULE_MAGIC;
#endif

PG_FUNCTION_INFO_V1(add_one_float8);

Datum
add_one_float8(PG_FUNCTION_ARGS)
{
    float8 arg = PG_GETARG_FLOAT8(0);
    PG_RETURN_FLOAT8(arg + 1.0);
}

関数を作成しようとすると:

   CREATE FUNCTION add_one(double precision) RETURNS double precision
   AS 'DIRECTORY\mylib.dll', 'add_one_float8'
   LANGUAGE C STRICT;

「エラー: 関数 "add_one_float8" が見つかりませんでした」というエラーが表示されますが、"pg_finfo_add_one_float8" で作成スクリプトが正常に終了しました。

関数名の前に「pg_finfo_」を追加するのは普通ですか、それとも間違っていますか?

PostgreSQL バージョン 9.1

ありがとうございました。

アップデート:

メイクファイル

PG_DIR=D:/Programs/PostgreSQL
PG_LIB=$(PG_DIR)/lib/postgres.lib
PG_INCLUDE_SERVER=$(PG_DIR)/include/server
PG_INCLUDE=$(PG_DIR)/include
PG_INCLUDE_PORT_WIN32=$(PG_DIR)/include/server/port/win32
PG_INCLUDE_PORT_WIN32_MSVC=$(PG_DIR)/include/server/port/win32_msvc
MSDK_INCLUDE="D:\Program Files\Microsoft SDKs\Windows\v7.0\Include"
COMPILER_INCLUDES=/I$(PG_INCLUDE) /I$(PG_INCLUDE_SERVER) /I  $(PG_INCLUDE_PORT_WIN32) /I$(PG_INCLUDE_PORT_WIN32_MSVC) /I$(MSDK_INCLUDE) 

LINKER_DLL_FLAGS=/MACHINE:X86
COMPILER_DLL_FLAGS=/c /TC /D "WIN32"

DLL_NAME=mylib
DLL_DEST=D:\lib

OBJS=myfunc.obj

.c.obj:
    cl $(COMPILER_DLL_FLAGS) $(COMPILER_INCLUDES) $*.c  

all:$(OBJS)
    link -out:$(DLL_DEST)\$(DLL_NAME).dll /DLL $(OBJS) $(PG_LIB)
4

2 に答える 2

2

Windows で拡張機能を構築するのは面倒です。それを行うための標準的で推奨される方法が本当にあるかどうかはわかりません。

カスタム makefileを使用してコンパイルする場合はnmake、適切なコンパイラ引数を指定する必要があります。

以下clは、Windows SDK 7.1 を使用して Windows ボックスでコア コードをビルドするときに呼び出されるものでsetenv /x86 /release /xp、すべて 1 行で記述されています。

C:\Program Files (x86)\Microsoft Visual Studio 10.0\VC\bin\CL.exe /c /Isrc/include /Isrc/include/port/win32 /Isrc/include/port/win32_msvc
/I"D:\libs\x86\Release\zlib-1.2.7\include" /Isrc\backend /Zi /nologo /W3 /WX- /Ox /Oy- /D WIN32 /D _WINDOWS /D __WINDOWS__ /D __WIN32__
/D EXEC_BACKEND /D WIN32_STACK_RLIMIT=4194304 /D _CRT_SECURE_NO_DEPRECATE /D _CRT_NONSTDC_NO_DEPRECATE /D BUILDING_DLL /D _USE_32BIT_TIME_T /D _MBCS /GF /Gm- /EHsc /MD /GS /fp:precise /Zc:wchar_t /Zc:forScope /Gd /TC /wd4018 /wd4244 /wd4273 /wd4102 /wd4090 /wd4267 /analyze- /errorReport:queue

Contrib モジュールには、おそらく多少異なるオプションがあります。詳しくは調べていません。ポイントは、ビルド時に渡される多くのコンパイラ フラグ (主に定義) があることです。

私が通常 Windows でモジュールをビルドする方法は、contrib/ ディレクトリにあるモジュールを使用して PostgreSQL ソース ツリーのコピーをビルドし、正規のモジュールを使用しbuild.plてコンパイルすることです。もっと賢明な方法があると確信しています。わざわざ探す必要はありません。

于 2012-12-08T11:23:33.963 に答える
0

問題は解決しました!

このコードは正常に動作します (ソース: http://www.ics.uci.edu/~jacobson/cs122b/Project/06-CFunctions.html )

/* Use 32-bit timer (provided header file uses 64-bit timer, not
 * compatible with Windows postgreSQL versions */
#define _USE_32BIT_TIME_T

/* Ensure that Pg_module_function and friends are declared __declspec(dllexport) */
#ifndef BUILDING_MODULE
#define BUILDING_MODULE
#endif

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

/*--------------- BEGIN REDEFINITION OF PG MACROS -------------------* 
 These rewritten versions of PG_MODULE_MAGIC and PG_FUNCTION_INFO_V1
 * declare the module functions as __declspec(dllexport) when building
 * a module. They also provide PGMODULEEXPORT for exporting functions
 * in user DLLs.
 */
#undef PG_MODULE_MAGIC
#undef PG_FUNCTION_INFO_V1

#define PGMODULEEXPORT __declspec (dllexport)

#define PG_MODULE_MAGIC \
PGMODULEEXPORT const Pg_magic_struct * \
PG_MAGIC_FUNCTION_NAME(void) \
{ \
    static const Pg_magic_struct Pg_magic_data = PG_MODULE_MAGIC_DATA; \
    return &Pg_magic_data; \
} \
extern int no_such_variable

#define PG_FUNCTION_INFO_V1(funcname) \
PGMODULEEXPORT 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

/*--------------- END REDEFINITION OF PG MACROS -------------------*/

PG_MODULE_MAGIC;

PG_FUNCTION_INFO_V1(add_one_float8);

PGMODULEEXPORT Datum add_one_float8(PG_FUNCTION_ARGS)
{
    float8   arg = PG_GETARG_FLOAT8(0);
    PG_RETURN_FLOAT8(arg + 1.0);
}

上記の質問のmakefileを使用してこのコードをコンパイルnmakeし、CREATE FUNCTIONコマンドを使用して関数をデータベースに追加する必要があります。

CREATE FUNCTION add_one(double precision) RETURNS double precision
AS 'DIRECTORY\mylib.dll', 'add_one_float8'
LANGUAGE C STRICT;
于 2012-12-09T09:22:16.297 に答える