Using Postgres connection functions
Adam D. Ruppe
destructionator at gmail.com
Sat Jan 20 04:54:47 UTC 2018
On Saturday, 20 January 2018 at 04:09:01 UTC, Joe wrote:
> 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.
A slight improvement here that removes the need for any casts
(and the extern(C) is useless here btw) is to just define it as
const(char)*:
const(char) * [2] pvs;
foreach (i, val; paramValues)
pvs[i] = toStringz(val);
Then you can call the argument with plain `pvs.ptr` instead of
casting it. Though, make sure you remember the null at the end
too!
> 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)?
const(char)*[] pvs = new const(char)*[](size_here);
// could also have been `auto pvs = ...;` btw
// then still pass it to pqFunc(pvs.ptr)
// the .ptr gets the char** out of it.
Just double check the documentation of any C function you pass it
to to make sure it doesn't explicitly say you must malloc it.
Some C functions will try to free() the pointer you pass it, or
may hold on to it. D's GC can't see pointers C functions keep, so
it might try to free that array any time after the local
variable `pvs` in D goes out of scope.
> 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?
Same as above. The general pattern is:
C_Type[] name = new C_Type[](requested_size);
// pass as `name.ptr`. This becomes a C_Type*
Just again, remember requested_size needs to include the null
terminator when C requires it, so a +1 might be helpful.
And also, no need for extern(C). That's more for function
declarations/pointers or maybe global variables C needs to be
able to see.
> 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).
Oh yikes, that would have been undefined behavior there. So [x]
on a pointer will just access memory past it - just like in C -
and might sometimes work, might sometimes overwrite other memory
(in your case, it probably overwrote some other local variable on
the stack), or, best case scenario really, might cause a
segmentation fault or access violation.
More information about the Digitalmars-d-learn
mailing list