On Mon, 2 Apr 2001 at 14:38:40 -0400, Sean MacLennan
<sean.maclennan(a)pika.ca> wrote:
I am currently working on a very simple interface to PostgreSQL
using
the libpq library. I have hacked up some code as a module to give me
the C to lisp interface (included in the first attachment).
Sounds cool!
I am not sure of the "correct" way to pass pointers back to
the
user. The user does not actually do anything with the pointers, just
passes them on to other routines. However, it would be useful for
debugging to be able to print the numbers.
So you want to give the user a handle which the user should not modify,
whose contents are irrelevant to the user, and whose contents are
relevant to the debugging process. In that case, you should probably
create your own data type. I'd do something like this:
------------------------------------------------------------------------
/* Some .h file */
struct pg_result
{
struct lcrecord_header header;
PGresult *res;
};
DECLARE_EXTERNAL_LRECORD (pg_result, struct pg_result);
#define XPG_RESULT(x) XRECORD (x, pg_result, struct pg_result)
#define XSETPG_RESULT(x, p) XSETRECORD (x, p, pg_result)
#define PG_RESULTP(x) RECORDP (x, pg_result)
#define CHECK_PG_RESULT(x) CHECK_RECORD (x, pg_result)
#define CONCHECK_PG_RESULT(x) CONCHECK_RECORD (x, pg_result)
#define XREALPG_RESULT(x) XPG_RESULT(x)->msg
extern Lisp_Object make_pg_result (PGresult *);
------------------------------------------------------------------------
/* Some .c file */
static void
print_pg_result (Lisp_Object obj, Lisp_Object printcharfun, int escapeflag)
{
PGresult *result = XPG_RESULT (obj);
/* Insert code to write result with printcharfun */
}
Lisp_Object
make_pg_result (PGresult *res_ptr)
{
struct pg_result *result;
Lisp_Object lisp_res;
result = alloc_lcrecord_type (struct pg_result, &lrecord_pg_result);
result->res = res_ptr;
XSETPG_RESULT (lisp_res, result);
return lisp_res;
}
DEFINE_EXTERNAL_LRECORD_IMPLEMENTATION ("pg-result", pg_result, 0,
print_pg_result, 0, 0, 0, 0,
struct pg_result);
void
syms_of_whatever_this_is (void)
{
INIT_EXTERNAL_LRECORD_IMPLEMENTATION (pg_result);
...
}
------------------------------------------------------------------------
Now the Lisp programmer will see Lisp objects of type pg-result coming
out of PQexec. You'd have to do something similar for a PGconn. This
isn't too bad as long as you don't have too many types that need to be
treated in such a manner.
A second question is the best way to allocate structures. I would
like
them to be normal lisp objects that GC etc., but that can be passed to
C functions. The opaque type looked perfect, except it has a warning
that the objects should never be passed up to lisp.
Use the same approach as above. I've got some examples of doing this
kind of thing here:
<
URL:http://www.ittc.ku.edu/~james/computer/viavoice.html>. That page
might move soon, since I appear to be getting around to doing something
about my pathetic web site today. I plan to eventually have it here:
<
URL:http://www.ittc.ku.edu/~james/xemacs/viavoice.html>.
--
Jerry James