Problems with string literals and etc.c.odbc.sql functions

anonymous via Digitalmars-d-learn digitalmars-d-learn at puremagic.com
Fri Dec 18 14:35:04 PST 2015


On 18.12.2015 23:14, Fer22f wrote:
> By the use of this tutorial
> (http://www.easysoft.com/developer/languages/c/odbc_tutorial.html), I
> thought it would be very straightforward to use etc.c.odbc.sqlext and
> etc.c.odbc.sql to create a simple odbc application. But as soon as I
> started, I noticed a quirk:
>
>      SQLRETURN ret;
>      SQLHDBC dbc;
>      ret = SQLDriverConnect(dbc, null, "DNS=*mydns*;", SQL_NTS,
>              null, 0, null, SQL_DRIVER_COMPLETE);
>
> This gives me an error: function etc.c.odbc.sqlext.SQLDriverConnect
> (void* hdbc, void* hwnd, char* szConnStrIn, short cbConnStrIn, char*
> szConnStrOut, short cbConnStrOutMax, short* pcbConnStrOut, ushort
> fDriverCompletion) is not callable using argument types (void*,
> typeof(null), string, int, typeof(null), int, typeof(null), int)
>
> After some casting, I found out it's all related to the string literal.
> I thought it would work straight off the box, after reading the
> "Interfacing to C" spec (http://dlang.org/spec/interfaceToC.html).
>
> When I remove the string literal and replace it with null, it compiles.
> .ptr and .toStringz both give immutable char* references, and don't
> work. A "cast(char *)"DNS=*maydns*;"" works, but it feels a lot like a
> hack that will not work in the long run.

If the parameter is de facto const, then the cast is ok. Though, maybe 
it should be marked const then.

If the parameter is really not const, i.e. the function may mutate the 
argument, then the cast is not ok. You can use `.dup.ptr` instead to get 
a proper char* from a string.

Also, remember that D's GC doesn't scan foreign memory. So if the 
function keeps the string around, and that's the only reference, then 
the GC would collect it. The function probably doesn't keep the string 
around, though.


More information about the Digitalmars-d-learn mailing list