Talk About Network

Google


Register and Login
Nick
Password
Register create new account Sign up is FREE and you can post replies, new topics, bookmark posts and more!
Recover lost password


Data Bases > Pgsql General > Re: Custom C fu...
Latest [ Topics | Posts ] Archive Post A New Topic Post a Reply
<< Topic < Post Post 9 of 23 Topic 15452 of 17602
Post > Topic >>

Re: Custom C function - is palloc broken?

by craig@[EMAIL PROTECTED] (Craig Ringer) May 5, 2008 at 03:54 PM

This is a multi-part message in MIME format.
--------------010702080904050305000502
Content-Type: text/plain; charset=ISO-8859-1; format=flowed
Content-Transfer-Encoding: 7bit

Nathan Thatcher wrote:
> So what options does that leave all of us who need to compile and run
> our custom C functions in Windows?

After a bit of sleep and with the advantage of a now-working brain I've 
got it working, at least with 8.3 .

The problem was with DLL linkage, especially the CurrentMemoryContext 
global variable. I was defining BUILDING_DLL and using the PGDLLIM****T 
macro to ex****t the copytext() function - but this was of course causing 
everything in the Pg headers to be declared __declspec(dllex****t) 
instead of __declspec(dllim****t) . AFAIK this is survivable for 
functions, which will use a slower call thunk instead, but not for 
ex****ted variables.

As a result, MemoryContextAlloc(CurrentMemoryContext, (sz)) was being 
called with a nonsensical pointer for CurrentMemoryContext and cra****ng.


To build the C function DLL correctly it correctly do not define the 
BUILDING_DLL macro. Instead, define your own DLL ex****t macros like:

#if defined(_MSC_VER) || defined(__MINGW32__)
#define COPYTEXT_EX****T __declspec (dllex****t)
#else
#define COPYTEXT_EX****T
#endif

then declare your function as:


COPYTEXT_EX****T Datum copytext2(PG_FUNCTION_ARGS) {
     // blah blah
}


It should now be ex****ted in the DLL's interface correctly AND have 
correct access to Pg's ex****ted functions and variables.

I did notice that I'm getting some warnings about inconsistent DLL 
linkage for Pg_magic_func and pg_finfo_copytext . These really need to 
be using __declspec(dllex****t) rather than using __declspec(dllim****t) 
via PGDLLIM****T .


Maybe it's worth providing a PGMODULEEX****T macro for PG_MODULE_MAGIC, 
PG_FUNCTION_INFO_V1, and for module writers to use to ex****t their 
functions in the DLL interface. A module author would have to ensure 
that BUILDING_MODULE was defined.

Here's how the PG_MODULE_MAGIC and PG_FUNCTION_INFO_V1 macros would look:

/* This might want to go somewhere other than fmgr.h, like
  * pg_config_os.h alongside the definition of PGDLLIM****T
  */
#if defined(_MSC_VER) || defined(__MINGW32__)
   #if defined(BUILDING_MODULE)
     #define PGMODULEEX****T __declspec (dllex****t)
   #else
     // Never actually used
     #define PGMODULEEX****T __declspec (dllim****t)
   #endif
#else
   #define PGMODULEEX****T
#endif

#define PG_MODULE_MAGIC \
PGMODULEEX****T  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) \
PGMODULEEX****T 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



I've tested this definition and it produces a DLL that links correctly 
and does so without the warnings of inconsistent DLL linkage produced by 
the original versions (which declared the function __declspec(dllim****t) 
then defined it).

Anyway, the C function examples need some changes to work correctly on 
win32. I've attached updated versions. These redefine the 
PG_MODULE_MAGIC and PG_FUNCTION_INFO_V1 macros, but if you omit that 
code the module will still built, just with warnings, and will still work.

--
Craig Ringer

--------------010702080904050305000502
Content-Type: text/plain;
 name="examples.c"
Content-Transfer-Encoding: 7bit
Content-Disposition: inline;
 filename="examples.c"

/*
 * PostgreSQL example C functions.
 * 
 * This file must be built as a shared library or dll and
 * placed into the PostgreSQL `lib' directory. On Windows
 * it must link to postgres.lib .
 *
 * postgresql/include/server must be on your header search path.
 * With MSVC++ on win32 so must postgresql/include/server/****t/win32_msvc
.
 * With MinGW use postgresql/include/server/****t/win32 .
 */

#if defined(_MSC_VER) || defined(__MINGW32__)
  #ifndef _USE_32BIT_TIME_T
    #define _USE_32BIT_TIME_T
  #endif
#endif

/* BUILDING_DLL causes the declarations in Pg's headers to be declared 
 * __declspec(dllex****t) which will break DLL linkage. */
#ifdef BUILDING_DLL
  #error Do not define BUILDING_DLL when building extension libraries
#endif

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

#include "postgres.h"
#include <string.h>
#include "fmgr.h"
#include "utils/geo_decls.h"

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

/* This might want to go somewhere other than fmgr.h, like
 * pg_config_os.h alongside the definition of PGDLLIM****T
 */
#if defined(_MSC_VER) || defined(__MINGW32__)
  #if defined(BUILDING_MODULE)
    #define PGMODULEEX****T __declspec (dllex****t)
  #else
    // Never actually used
    #define PGMODULEEX****T __declspec (dllim****t)
  #endif
#else
  #define PGMODULEEX****T
#endif

#define PG_MODULE_MAGIC \
PGMODULEEX****T  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) \
PGMODULEEX****T 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);

PGMODULEEX****T Datum
add_one(PG_FUNCTION_ARGS)
{
    int32   arg = PG_GETARG_INT32(0);

    PG_RETURN_INT32(arg + 1);
}

/* by reference, fixed length */

PG_FUNCTION_INFO_V1(add_one_float8);

PGMODULEEX****T Datum
add_one_float8(PG_FUNCTION_ARGS)
{
    /* The macros for FLOAT8 hide its pass-by-reference nature. */
    float8   arg = PG_GETARG_FLOAT8(0);

    PG_RETURN_FLOAT8(arg + 1.0);
}

PG_FUNCTION_INFO_V1(makepoint);

PGMODULEEX****T Datum
makepoint(PG_FUNCTION_ARGS)
{
    /* Here, the pass-by-reference nature of Point is not hidden. */
    Point     *pointx = PG_GETARG_POINT_P(0);
    Point     *pointy = PG_GETARG_POINT_P(1);
    Point     *new_point = (Point *) palloc(sizeof(Point));

    new_point->x = pointx->x;
    new_point->y = pointy->y;
       
    PG_RETURN_POINT_P(new_point);
}

/* by reference, variable length */

PG_FUNCTION_INFO_V1(copytext);

PGMODULEEX****T Datum
copytext(PG_FUNCTION_ARGS)
{
    text     *t = PG_GETARG_TEXT_P(0);
    /*
     * VARSIZE is the total size of the struct in bytes.
     */
    text     *new_t = (text *) palloc(VARSIZE(t));
    SET_VARSIZE(new_t, VARSIZE(t));
    /*
     * VARDATA is a pointer to the data region of the struct.
     */
    memcpy((void *) VARDATA(new_t), /* destination */
           (void *) VARDATA(t),     /* source */
           VARSIZE(t) - VARHDRSZ);  /* how many bytes */
    PG_RETURN_TEXT_P(new_t);
}

PG_FUNCTION_INFO_V1(concat_text);

PGMODULEEX****T Datum
concat_text(PG_FUNCTION_ARGS)
{
    text  *arg1 = PG_GETARG_TEXT_P(0);
    text  *arg2 = PG_GETARG_TEXT_P(1);
    int32 new_text_size = VARSIZE(arg1) + VARSIZE(arg2) - VARHDRSZ;
    text *new_text = (text *) palloc(new_text_size);

    SET_VARSIZE(new_text, new_text_size);
    memcpy(VARDATA(new_text), VARDATA(arg1), VARSIZE(arg1) - VARHDRSZ);
    memcpy(VARDATA(new_text) + (VARSIZE(arg1) - VARHDRSZ),
           VARDATA(arg2), VARSIZE(arg2) - VARHDRSZ);
    PG_RETURN_TEXT_P(new_text);
}


--------------010702080904050305000502
Content-Type: text/plain
Content-Disposition: inline
Content-Transfer-Encoding: 8bit
MIME-Version: 1.0


-- 
Sent via pgsql-general mailing list (pgsql-general@[EMAIL PROTECTED]
)
To make changes to your subscription:
http://www.postgresql.org/mailpref/pgsql-general

--------------010702080904050305000502--
 




 23 Posts in Topic:
Custom C function - is palloc broken?
n8thatcher@[EMAIL PROTECT  2008-05-03 21:39:04 
Re: Custom C function - is palloc broken?
craig@[EMAIL PROTECTED]   2008-05-04 23:50:26 
Re: Custom C function - is palloc broken?
craig@[EMAIL PROTECTED]   2008-05-04 23:52:41 
Re: Custom C function - is palloc broken?
heron@[EMAIL PROTECTED]   2008-05-04 13:02:49 
Re: Custom C function - is palloc broken?
craig@[EMAIL PROTECTED]   2008-05-05 05:53:27 
Re: Custom C function - is palloc broken?
magnus@[EMAIL PROTECTED]   2008-05-04 21:15:49 
Re: Custom C function - is palloc broken?
craig@[EMAIL PROTECTED]   2008-05-05 06:47:11 
Re: Custom C function - is palloc broken?
n8thatcher@[EMAIL PROTECT  2008-05-04 21:53:01 
Re: Custom C function - is palloc broken?
craig@[EMAIL PROTECTED]   2008-05-05 15:54:13 
Re: Custom C function - is palloc broken?
heron@[EMAIL PROTECTED]   2008-05-05 09:26:22 
Re: Custom C function - is palloc broken?
heron@[EMAIL PROTECTED]   2008-05-05 16:57:08 
Re: Custom C function - is palloc broken?
heron@[EMAIL PROTECTED]   2008-05-05 18:47:50 
Re: Custom C function - is palloc broken?
craig@[EMAIL PROTECTED]   2008-05-06 08:42:16 
Re: Custom C function - is palloc broken?
heron@[EMAIL PROTECTED]   2008-05-05 19:42:01 
Re: Custom C function - is palloc broken?
craig@[EMAIL PROTECTED]   2008-05-06 10:19:32 
Re: Custom C function - is palloc broken?
tgl@[EMAIL PROTECTED] (T  2008-05-05 22:32:11 
Re: Custom C function - is palloc broken?
craig@[EMAIL PROTECTED]   2008-05-06 12:02:28 
Re: Custom C function - is palloc broken?
heron@[EMAIL PROTECTED]   2008-05-05 20:45:05 
Re: Custom C function - is palloc broken?
jd@[EMAIL PROTECTED] (&q  2008-05-05 20:18:42 
Re: Custom C function - is palloc broken?
tgl@[EMAIL PROTECTED] (T  2008-05-05 22:22:43 
Re: Custom C function - is palloc broken?
magnus@[EMAIL PROTECTED]   2008-05-05 09:07:37 
Re: Custom C function - is palloc broken?
dpage@[EMAIL PROTECTED]   2008-05-06 09:46:14 
Re: Custom C function - is palloc broken?
dpage@[EMAIL PROTECTED]   2008-05-06 09:48:43 

Post A Reply:
  Go here to Signup

AddThis Feed Button


About - Advertising - Contact - Frequently Asked Questions - Privacy Policy - Terms of Use - Signup

Contact
tan12V112 Mon Dec 1 19:30:59 CST 2008.