Problem with correct compiling and linking server side C function on Windows ,c++ Builder

From: Maciej Grygorcewicz <prometeusz1(at)o2(dot)pl>
To: pgsql-hackers(at)postgresql(dot)org
Subject: Problem with correct compiling and linking server side C function on Windows ,c++ Builder
Date: 2008-01-18 18:30:41
Message-ID: 7a197ea.15c87407.4790f051.cb993@o2.pl
Views: Raw Message | Whole Thread | Download mbox | Resend email
Thread:
Lists: pgsql-hackers


Hello
I tried to find soultion for this problem on -cygwin list , but there they sent me to teh list -win32.
But I foun on the site that this is that list (also -hacker-win32),so I came here to -hackers.
My problem is as follows , maybe you can help me....:
I ma working on
a server-side function written in &quot;C&quot; which should get a bytea type
image - simple jpg picture , resize and compress it with defined
paramters and return also a bytea type. I made working test code that
worked fine as a console program.
My boss demands it to be compiled in Windows (postgreSQL server
is running on Windows 2003) , so I created this project in Borland
C++ Builder 6.0.
I am not using Cygwin.
PostgreSQL C external function has to be built into dll , so I created new project DLL Wizard - C style dll.
Later I changed some code , and pasted it to the DLL &quot;C&quot; style , and wanted to build dll.
My Code:
-----------------------------------------------------------------------------
#include &quot;postgres.h
&quot;
#include &lt;windows.h&gt;
#include &lt;io.h&gt;
#include &lt;fcntl.h&gt;
#include &lt;stat.h&gt;
#include &lt;setjmp&gt;
#include &quot;jerror.h&quot;
#include &quot;jpeglib.h&quot;

#pragma argsused
extern __declspec(dllexport) bytea* kompresuj(bytea* obrazek,int zdjwyj_sz, int zdjwyj_w,int stkompr);
int WINAPI DllEntryPoint(HINSTANCE hinst, unsigned long reason, void* lpReserved)
{
return 1;
}
struct my_error_mgr {
struct jpeg_error_mgr pub;
jmp_buf setjmp_buffer;
};
typedef struct my_error_mgr *my_error_ptr;
void my_error_exit(j_common_ptr cinfo)
{
my_error_ptr myerr = (my_error_ptr) cinfo-&gt;err;
(*cinfo-&gt;err-&gt;output_message) (cinfo);
longjmp(myerr-&gt;setjmp_buffer, 1);
}
int czytajwymiarywej(char *filename,int wymiary[])
{ struct jpeg_decompress_struct cinfo;
struct my_error_mgr jerr;
FILE *infile;
if ((infile = open(filename, O_RDONLY|O_BINARY,S_IREAD)) == NULL) {
return -1;
}
jerr.pub.error_exit = my_error_exit;
cinfo.err = jpeg_std_error(&amp;jerr.pub);
jpeg_CreateDecompress(&amp;cinfo,JPEG_LIB_VERSION,(size_t)sizeof(cinfo));
if (setjmp(jerr.setjmp_buffer)) {
jpeg_destroy_decompress(&amp;cinfo);
fclose(infile);
return -2;
}
jpeg_stdio_src(&amp;cinfo, infile);
(void) jpeg_read_header(&amp;cinfo, TRUE);
wymiary[0] = cinfo.image_width;
wymiary[1] = cinfo.image_height;
jpeg_destroy_decompress(&amp;cinfo);
return 0;
}
int read_jpeg(j_decompress_ptr cinfoptr, unsigned char **image_buffer,int *image_width, int *image_height)
{ JSAMPARRAY jpeg_buffer;
long int i_buffer, i_image;
(void) jpeg_start_decompress(cinfoptr);
*image_buffer = (unsigned char *) malloc(*image_width *
*image_height * (*cinfoptr).out_color_components* sizeof(unsigned
char));
if (*image_buffer == NULL) {
(void) jpeg_finish_decompress(cinfoptr);
jpeg_destroy_decompress(cinfoptr);
return -3;
}

jpeg_buffer = (*(*cinfoptr).mem-&gt;alloc_sarray)((j_common_ptr)
cinfoptr, JPOOL_IMAGE,(*cinfoptr).output_width *
(*cinfoptr).output_components, 1);
i_image = 0;
while ((*cinfoptr).output_scanline &lt; (*cinfoptr).output_height) {
(void) jpeg_read_scanlines(cinfoptr, jpeg_buffer, 1);
if ((*cinfoptr).output_components == 3) {
for (i_buffer = 0; (unsigned)i_buffer &lt;
(*cinfoptr).output_width * (*cinfoptr).output_components; i_buffer++,
i_image++)
(*image_buffer)[i_image] = jpeg_buffer[0][i_buffer];
}
}
(void) jpeg_finish_decompress(cinfoptr);
jpeg_destroy_decompress(cinfoptr);
return 0;
}
int write_jpeg(j_compress_ptr cinfoptr, unsigned char *image_buffer,int quality, int image_width, int image_height)
{ JSAMPROW row_pointer[1];
if (quality &lt; 0) quality = 0; else if(quality &gt; 100) quality = 100;
jpeg_set_quality(cinfoptr, quality, FALSE);
jpeg_start_compress(cinfoptr, TRUE);
while ((*cinfoptr).next_scanline &lt; (*cinfoptr).image_height) {
row_pointer[0] = &amp;image_buffer[(*cinfoptr).next_scanline* image_width * (*cinfoptr).input_components];
(void) jpeg_write_scanlines(cinfoptr, row_pointer, 1);
}
jpeg_finish_compress(cinfoptr);
jpeg_destroy_compress(cinfoptr);
return 0;
}
bytea* kompresuj(bytea* obrazek,int zdjwyj_sz, int zdjwyj_w,int stkompr)
{
int rc;unsigned char *zdjwej,*zdjwyj;
int zdjwej_w, zdjwej_sz;
int jakosc,i, j, k, ib, jb; double ratio;
int rozmiar;
bytea* zdjwyjwyn;
/* Dekompresja - ustawianie obiektu cinfo */
struct jpeg_decompress_struct cinfo;
struct my_error_mgr jerr;
/* Kompresja dane do kompresji */
struct jpeg_compress_struct cinfokompr;
struct my_error_mgr jerr1;
/* ------------------------*/
//typedef void* declspec(dllimport) funkcjaTYP (MemoryContext,Size);
//HINSTANCE uchwytDLL = LoadLibrary(&quot;libecpg.dll&quot;);
//funkcjaTYP *funkcja = (funkcjaTYP*) GetProcAddress(uchwytDLL, &quot;_MemoryContextAlloc&quot;);
jerr.pub.error_exit = my_error_exit;
cinfo.err = jpeg_std_error(&amp;jerr.pub);
jpeg_CreateDecompress(&amp;cinfo,JPEG_LIB_VERSION,(size_t)sizeof(cinfo));
if (setjmp(jerr.setjmp_buffer)) {
jpeg_destroy_decompress(&amp;cinfo);
};
jpeg_stdio_src(&amp;cinfo, (FILE*)obrazek-&gt;vl_dat);
(void) jpeg_read_header(&amp;cinfo, TRUE);
cinfo.dct_method = JDCT_FLOAT;
cinfo.scale_denom
= 1;
cinfo.do_block_smoothing = true;
cinfo.out_color_space = JCS_RGB;
cinfo.quantize_colors = 0;
//info.desired_number_of_colors = wymilosckolbmp;
cinfo.two_pass_quantize = true;
cinfo.dither_mode = JDITHER_ORDERED;
if (zdjwej_sz &gt; zdjwej_w)
{
ratio = zdjwyj_sz / (double)zdjwej_sz;
zdjwyj_w = (int)((double)zdjwej_w * ratio);
}
else
{
ratio = zdjwyj_w / (double)zdjwej_w;
zdjwyj_sz = (int)((double)zdjwej_sz * ratio);
}
rc = read_jpeg(&amp;cinfo, &amp;zdjwej ,&amp;zdjwej_sz, &amp;zdjwej_w);
if (rc != 0) {jpeg_destroy_decompress(&amp;cinfo);}
else
{
zdjwyj = (unsigned char*)malloc(zdjwyj_sz * zdjwyj_w *cinfo.output_components * sizeof(unsigned char));
for (j = 0; j &lt; zdjwyj_w; j++)
{
jb = (int)((double)j / ratio);
for (i = 0; i &lt; zdjwyj_sz; i++)
{
ib = (int)((double)i / ratio);

for (k = 0; k &lt; 3; k++) zdjwyj[(j * zdjwyj_sz + i) * 3 + k]=
zdjwej[(jb * zdjwej_sz + ib) * 3 + k];
}
}
free(zdjwej);
jerr1.pub.error_exit = my_error_exit;
cinfokompr.err = jpeg_std_error(&amp;jerr1.pub);
jpeg_create_compress(&amp;cinfokompr);
//zdjwyjwyn = (bytea*) palloc(sizeof(bytea));
jpeg_stdio_dest(&amp;cinfokompr, (FILE*)zdjwyjwyn-&gt;vl_dat);
cinfokompr.image_width = zdjwyj_sz;

cinfokompr.image_height = zdjwyj_w;
cinfokompr.in_color_space = JCS_RGB;
jpeg_set_defaults(&amp;cinfokompr);
cinfokompr.dct_method = JDCT_FLOAT;
jpeg_set_linear_quality(&amp;cinfokompr, 80,0);
cinfokompr.smoothing_factor = 20;

rc = write_jpeg(&amp;cinfokompr,zdjwyj,stkompr,zdjwyj_sz, zdjwyj_w);
free(zdjwyj);
if (rc!= 0) return NULL ;
return zdjwyjwyn;
}
return NULL;
}
--------------------------------------
But linker threw such errors:
&quot;
Unresolved External: _pgwin32_fopen referended from .... // and so on
Unresolved External: _pg_sprintfl referended from .... // and so on &quot;
Why???? I have included postgres.h , and all other required files .
I tried to build almost the same code but in C++ style DLL.
DLL file was created succesfully , but on the other hand postgreSQL couldn't find exported function...
DLL was in non-undernstadable format for postgresql.
Is it fault of windows??? Have I to use Cygwin , and cygwin include and library files to successfully build this function??
Ahh , function has to be called by a Trigger ...
Can you advice me some solution???
Maciej Grygorcewicz
maciekgrygorcewicz ( at ) gmail ( dot ) com ,
prometeusz1 ( at ) o2 ( dot ) pl
GG 1638280
--
Pozdrawiam
Maciej Grygorcewicz
Prometeusz1(at)o2(dot)pl
kom 0602471330
GG 1638280

Browse pgsql-hackers by date

  From Date Subject
Next Message Pavel Stehule 2008-01-18 18:33:57 proposal: generic function, constructor function
Previous Message Darcy Buskermolen 2008-01-18 15:53:37 Re: Simple thing to make pg_autovacuum more useful