Thread: Link error: LNK2019: unresolved external symbol _pg_detoast_datum

Link error: LNK2019: unresolved external symbol _pg_detoast_datum

From
"Ale Raza"
Date:

Hi,

 

I want to add a user defined function using “Version-1 Calling Conventions” but getting a link error.

I am using MS Visual C++ .NET (V 7.1.3) on Win XP SP 2. PostgreSQL 8.1.3.

 

Am I missing some lib or some other file?

 

I saw earlier thread “building and linking C user defined functions” and set the complier setting to /FORCE. It create the dll but the following SQL crash psql

 

Select filesize('my file');

 

Here is the simplified version of my problem.

 

ERROR:

------ Rebuild All started: Project: copytext, Configuration: Debug Win32 ------

 

Deleting intermediate files and output files for project 'copytext', configuration 'Debug|Win32'.

Compiling...

copytext.c

Linking...

   Creating library Debug/copytext.lib and object Debug/copytext.exp

copytext.obj : error LNK2019: unresolved external symbol _MemoryContextAlloc referenced in function _copytext

copytext.obj : error LNK2001: unresolved external symbol __imp__CurrentMemoryContext

copytext.obj : error LNK2019: unresolved external symbol _pg_detoast_datum referenced in function _copytext

Debug/copytext.dll : fatal error LNK1120: 3 unresolved externals

 

Build log was saved at "file://..\copytext\Debug\BuildLog.htm"

copytext - 4 error(s), 0 warning(s)

 

 

File copytext.c:

#include "postgres.h"

#include <string.h>

#include "fmgr.h"

 

PG_FUNCTION_INFO_V1(copytext);

Datum

copytext(PG_FUNCTION_ARGS)

{

text *t = PG_GETARG_TEXT_P(0);

/*

………

PG_RETURN_TEXT_P(new_t);

}

 

I can do this on Linux but looks like windows have some issues.

 

Thanks.

 

Ale Raza.

 

Re: Link error: LNK2019: unresolved external symbol _pg_detoast_datum

From
"Taras Kopets"
Date:
Hi!
 
You can compile it with MinGW - www.mingw.org.
 
My test function was just a simple one for writing text to file:
=============== FILE =================
#include "postgres.h"
#include <string.h>
#include "fmgr.h"
#include "utils/builtins.h"
#include "storage/fd.h"
 
PG_FUNCTION_INFO_V1(writelog_tofile);
 
Datum
writelog_tofile(PG_FUNCTION_ARGS)
{
  FILE  *pFile; 
  text  *txt_fpath  = PG_GETARG_TEXT_P(0); 
  text  *txt_fname  = PG_GETARG_TEXT_P(1);
  text  *txt_writxt = PG_GETARG_TEXT_P(2);
 
  char *filepath; 
  char *writetext;
  char *abspath;  
  int32  abspath_size = VARSIZE(txt_fpath) + VARSIZE(txt_fname) - VARHDRSZ;
  text *txt_abspath = (text *) palloc(abspath_size);
 
  VARATT_SIZEP(txt_abspath) = abspath_size;
  memcpy(VARDATA(txt_abspath), VARDATA(txt_fpath), VARSIZE(txt_fpath)-VARHDRSZ);
  memcpy(VARDATA(txt_abspath) + (VARSIZE(txt_fpath)-VARHDRSZ),
           VARDATA(txt_fname), VARSIZE(txt_fname)-VARHDRSZ);
   
  abspath  = DatumGetCString(DirectFunctionCall1(textout, PointerGetDatum(txt_abspath)));
  filepath = DatumGetCString(DirectFunctionCall1(textout, PointerGetDatum(txt_fpath))); 
 
  pFile = AllocateFile(abspath, "a");
  if (!pFile) {
    mkdir(filepath, S_IRWXU);
    pFile = AllocateFile(abspath, "a");
    if(!pFile)
    ereport(WARNING,
              (errcode_for_file_access(),
                  errmsg("could not open file \"%s\" for writing: %m", abspath)));
  }
 
  if (pFile) {
    writetext = DatumGetCString(DirectFunctionCall1(textout, PointerGetDatum(txt_writxt)));
    fprintf(pFile, "%s\n", writetext);
  }
 
  if (pFile) {
    if (FreeFile(pFile)) {
      ereport(WARNING,
                (errcode_for_file_access(),
                    errmsg("could not write to file \"%s\": %m", abspath)));
    }
  }
}
 
=========== END OF FILE ==============
Or you can use example code from PostgreSQL manual.
 
To compile this code I installed MinGW+MinSYS:
 
MinGW to c:\MinGW with next modules:
mingw-runtime-3.9.tar.gz
gcc-core-3.4.2-20040916-1.tar.gz
binutils-2.15.91-20040904-1.tar.gz
mingw32-make-3.80.0-3.tar.gz
w32api-3.7.tar.gz
 
And MinSYS to c:\msys:
MSYS-1.0.10.exe
 
To compile the source you will need header files to compile, I used header files which comes with my PostgreSQL 8.1.4 Windows binary installation (include directory):
Then created dirs:
[e:\pg]
[e:\pg\cdev]
and copied directory [include] which can be optionally installed when installing PostgreSQL in my case from [c:\Program Files\PostgreSQL\8.1\] to [e:\pg\cdev\].
You can skip this, but later you will need to write the full path (probably double quoted) to your include dir.
 
To make it compile I changed the line: [#define ENABLE_NLS 1]
to [#undef ENABLE_NLS] in the file e:\pg\cdev\include\pg_config.h
 
I placed the code of my function to [e:\pg\cdev\writetofile.c].
 
Then run MinSYS and type this line:
[gcc -c e:/pg/cdev/writetofile.c -o e:/pg/cdev/writetofile.o -I e:/pg/cdev/include -I e:/pg/cdev/include/server -I e:/pg/cdev/include/server/port/win32]
(without brackets [], and remember to use / instead of \)
This command created object file in  [e:\pg\cdev\writetofile.o].
 
Then to get "DLL" which can be linked to PostgreSQL type this:
[gcc -shared  e:/pg/cdev/writetofile.o -o e:/pg/cdev/writetofile.dll -L "C:/Program Files/PostgreSQL/8.1/lib" -lpostgres]
 
This will create a file [e:\pg\cdev\writetofile.dll].
Then copy this file to my PostgreSQL lib directory [C:\Program Files\PostgreSQL\8.1\lib].
 
The last thing left to do is to create a procedure in PostgreSQL which will use this code.
We can make it with this SQL code:
CREATE OR REPLACE FUNCTION writetofile(text, text, text) RETURNS void
     AS '$libdir/writetofile', 'writelog_tofile'
     LANGUAGE C STRICT;
 
Use it.
Best Regards,
Taras Kopets
----- Original Message -----
From: Ale Raza
Sent: Thursday, October 19, 2006 1:28 AM
Subject: [GENERAL] Link error: LNK2019: unresolved external symbol _pg_detoast_datum

Hi,

 

I want to add a user defined function using “Version-1 Calling Conventions” but getting a link error.

I am using MS Visual C++ .NET (V 7.1.3) on Win XP SP 2. PostgreSQL 8.1.3.

 

Am I missing some lib or some other file?

 

I saw earlier thread “building and linking C user defined functions” and set the complier setting to /FORCE. It create the dll but the following SQL crash psql

 

Select filesize('my file');

 

Here is the simplified version of my problem.

 

ERROR:

------ Rebuild All started: Project: copytext, Configuration: Debug Win32 ------

 

Deleting intermediate files and output files for project 'copytext', configuration 'Debug|Win32'.

Compiling...

copytext.c

Linking...

   Creating library Debug/copytext.lib and object Debug/copytext.exp

copytext.obj : error LNK2019: unresolved external symbol _MemoryContextAlloc referenced in function _copytext

copytext.obj : error LNK2001: unresolved external symbol __imp__CurrentMemoryContext

copytext.obj : error LNK2019: unresolved external symbol _pg_detoast_datum referenced in function _copytext

Debug/copytext.dll : fatal error LNK1120: 3 unresolved externals

 

Build log was saved at "file://..\copytext\Debug\BuildLog.htm"

copytext - 4 error(s), 0 warning(s)

 

 

File copytext.c:

#include "postgres.h"

#include <string.h>

#include "fmgr.h"

 

PG_FUNCTION_INFO_V1(copytext);

Datum

copytext(PG_FUNCTION_ARGS)

{

text *t = PG_GETARG_TEXT_P(0);

/*

………

PG_RETURN_TEXT_P(new_t);

}

 

I can do this on Linux but looks like windows have some issues.

 

Thanks.

 

Ale Raza.

 

Re: Link error: LNK2019: unresolved external symbol _pg_detoast_datum

From
"Taras Kopets"
Date:
Hi,

Ale Raza wrote:
>> Ok, it means I can not use MS VC complier/linker, only choice is Mingw or Cygwin.

I think you can use MS VC, you can try to find some info from here:
http://www.postgresql.org/docs/8.0/interactive/xfunc-c.html
Read user comments at the bottom.


Ale Raza wrote:
>> Wondering if you know which process (Postmaster.exe or Postgres.exe)
>> I have to attach in order to debug this type of functions.
>> I have more complex functions where I need debugger.


In documentation it is said:
"The first time a user-defined function in a particular loadable object file is called in a session, the dynamic loader loads that object file into memory so that the function can be called", so I think you should try to attach to postgres.exe (I'm not sure).


Have a nice day,
Taras Kopets