On Saturday, 13 January 2018 at 05:28:17 UTC, Joe wrote:
Going beyond the connection, there are various other libpq
functions that use a similar pattern of values passed using
multiple parallel C arrays, e.g.,
PGresult *PQexecParams(PGconn *conn,
const char *command,
int nParams,
const Oid *paramTypes,
const char * const *paramValues,
const int *paramLengths,
const int *paramFormats,
int resultFormat);
Each of the `paramXxxxs' arguments are arrays (Oid is an alias
for uint).
[...]
Focusing on the above function, suppose the first two parameter
arrays are defined in a C program as:
Oid paramTypes[] = {23, 25};
char *paramValues[] = {"1", "abcde"};
which could be expressed in D as:
Oid [] paramTypes = [23, 25];
string [] paramValues = ["1", "abcde"];
I know the paramTypes could be passed as null, letting PG deduce
the data types but suppose we have some reason to accumulate
types, etc., in D slices. I know the paramValues can be
manipulated in a manner similar to the one shown in my first
post, namely something like this:
extern(C) char * [2] pvs;
foreach (i, val; paramValues)
pvs[i] = cast(char *)toStringz(val);
And then use "cast(const char **)pvs" for the paramValues
argument. The only feedback that I received that was explicit to
this approach was in response to my initial post, in which Adam
D. Ruppe said that what I did was "decent".
So I have two lingering doubts:
1. Is malloc() the only way to allocate the arrays, either of
Oid's, int's or char *'s, for passing to the libpq functions?
IOW, isn't there a way to take advantage of D's 'new' (and thus
the GC)?
2. How to convert a slice of Oid's or int's to an array of
pointers suitable by processing by the libpq C function? A
technique similar to the previous one seems to work, e.g.,
extern(C) Oid [2] pts;
foreach (i, typ; paramTypes)
pts[i] = typ;
But I'm not sure if it's really working (when I mistakenly had a
* in the pts declaration, at one point it also seemed to work).