Charles F. I. Savage wrote: > Hi everyone, > > I've been able to successfully build server extension using Visual > Studio 2005 for Windows Postgresql 8.1. However, it took a few tweaks > which I thought I should document (maybe these issues could be fixed in > future postgresql versions?):
Sorry for the delay in replying to your issues. > 1. There is no lib file for VC++ to link against. This can be created > easily enough by going to src/backend directory and running: > > lib /MACHINE:x86 /NAME:postgres.exe /DEF:postgres.def > > Note the use of /NAME to tell VC++ it is linking against an executable > and not a dll. > > It would be nice if this lib file was automatically installed on windows > when installing postgresql. We don't distribute a *.def file in this case because it would be too hard to keep it up-to-date. We have *.def files for libpq, but that changes much less frequently than the backend. The most reliable solution is for users to generate the file themselves. > 2. Requirement on strings.h > > In c.h:69 there is this code: > > #ifdef HAVE_STRINGS_H > #include <strings.h> > #endif > > > In pg_config.h:405 this is defined: > > /* Define to 1 if you have the <strings.h> header file. */ > #define HAVE_STRINGS_H 1 > > However, Visual Studio 2005 does not include this file. For a > workaround I simply added it but that's a bit of hack. Ah, so even though you are using MSVC, you are using the config file from MinGW. Easy fix, included in the patch below, and applied for 8.2. > 3. This is a bigger issue, and took a while to figure out. If you try > to use the Version 1 calling convention, your function will be called > but if you try to do anything with the passed in parameters a > segmentation fault will occur. If you use the Version 0 calling > convention things work fine. > > The problem is if you use PG_FUNCTION_INFO_V1 postgres does not see the > generated function because it is not exported from the dll and thus > assumes the Version 0 calling convention when in fact your function is > using Version1. The problem is in fmgr.h:298 > > #define PG_FUNCTION_INFO_V1(funcname) \ > > extern Pg_finfo_record * CppConcat(pg_finfo_,funcname) (void); \ > ... > > For windows to export this function it must be: > > extern __declspec(dllexport) Pg_finfo_record * > CppConcat(pg_finfo_,funcname) (void); > > Would it be possible to add a DLLEXPORT macro here to fix this? Yes, we can add DLLIMPORT (which is our macro for that). However, looking at why /contrib works for MinGW, I think it is the use of this from Makefile.shlib: $(DLLTOOL) --export-all $(DLLTOOL_DEFFLAGS) --output-def $(NAME).def $(OBJS) I am thinking you should just do the same for MSVC. Should we add DLLIMPORT to PG_FUNCTION_INFO_V1()? It duplicates --export-all but it seems like the correct solution. > 4. Last, and the biggest issue, if my function calls pfree it blows > up. What is happening is that pfree somehow ends up pointing to a > random spot in memory - thus when you try to call it you execute invalid > code (in fact you never execute pfree at all as far as I can see). I > worked around this by using pgport_pfree which does work. Haven't a > clue why... The answer is in a comment just above pgport_palloc(): /* * Memory support routines for libpgport on Win32 * * Win32 can't load a library that DLLIMPORTs a variable * if the link object files also DLLIMPORT the same variable. * For this reason, libpgport can't reference CurrentMemoryContext * in the palloc macro calls. * * To fix this, we create several functions here that allow us to * manage memory without doing the inline in libpgport. */ -- Bruce Momjian http://candle.pha.pa.us SRA OSS, Inc. http://www.sraoss.com + If your life is a hard drive, Christ can be your backup. +
Index: src/include/c.h =================================================================== RCS file: /cvsroot/pgsql/src/include/c.h,v retrieving revision 1.196 diff -c -c -r1.196 c.h *** src/include/c.h 16 Feb 2006 23:23:50 -0000 1.196 --- src/include/c.h 3 Mar 2006 17:13:57 -0000 *************** *** 66,72 **** #include <string.h> #include <stddef.h> #include <stdarg.h> ! #ifdef HAVE_STRINGS_H #include <strings.h> #endif #include <sys/types.h> --- 66,73 ---- #include <string.h> #include <stddef.h> #include <stdarg.h> ! /* Some use MinGW-generated pg_config.h but MSVC for extensions. */ ! #if defined(HAVE_STRINGS_H) && !defined(WIN32_CLIENT_ONLY) #include <strings.h> #endif #include <sys/types.h>
---------------------------(end of broadcast)--------------------------- TIP 5: don't forget to increase your free space map settings