I think returning the numeric pointer is the normal behavior for DllCall() andrdonnay wrote: I am interested in why your aliased functions
( example:
@sqlite3:sqlite3_column_name(stmt,n) ) seem to work properly whereas DLLFUNCTION
can produce IDSC's and wrong returned values.
This causes an error because it returns a numeric instead of a string:
sqlite3_column_name( stmt, 2 )
DLLFUNCTION sqlite3_column_name( stmt, n ) USING CDECL FROM sqlite3.dll
also for nFpCall() and the related @dll:func() xtranslate
In both cases the result is taked from the EAX register after the functions end
nFpCall() is faster than DllCall(), have more flexibility accepting params,
automatically detect the calling convention or excess of params and fix the
stack if needed, but I think using CDECL in DllCall() and passing the right
number of parameters must give you no troubles.
There are another cases where the called function returns double or int64 and
obviously DllCall() will return EAX that is meaningles in the double case and
just the lower half of the value in the int64 case. ot4xb provide functions
ndFpCall() that get the value from fstp and qwFpCall() that get the return value
by combining EAX with EDX.
QFpCall() and the corresponding @dll:[prototype]:function() xtranslate will
coerce the params and return values to the types supplied in the prototype,
oposite the other *FpCall() functions that use the provided param values to
infer the param types. With this syntax BOOL functions will return .T./.F. and
a Xbase++ string if c_sz is specified in the template
Except for the functions returning 64 bit integer or float values I thinkrdonnay wrote: I used DLLFUNCTION wrappers for every function in the ACE32.DLL (Ads) library
with no problems like this.
Never a problem.
Yet SQLite3.dll seems to not work with DLLFUNCTION calls.
cannot see any obvious reason to make DLLFUNTION fail. Of course you must
provide the right number of parameters and the CDECL calling convention.
Yes is a very simple mechanism. If you take a look to my fpCall.cpp file yourdonnay wrote: I assume that you are creating some kind of dynamic call from inside OT4XB.dll.
will fount this code arround line 103.
Code: Select all
// push params onto the stack in reverse order
for( n = nParams-1; n >= 0 ; n-- )
{
if( pParams[n].m_nSplit < 3 )
{
DWORD dw = pParams[n].m_dwStackVal;
_asm mov eax , dw;
_asm push eax;
}
}
_asm mov eax , dwFPtr;
_asm call eax; // call the function
_asm mov nl ,eax; // get the result
I've attached a small modification I was made to the class in order to coerce the typesrdonnay wrote: I could probably create a complete set of SQLite3_*() function calls by using
your technique,
of the resulting columns, just by providing an optional template string with the desired types.
// C - Ansi string
// T - Utf8 string untransformed
// I - integer
// F - double
// B - blob
Code: Select all
stm := db:exec_beginA("SELECT id,rnd,uuid,length(memo) FROM t")
aa := db:exec_end_ex(stm,,,"IICI" )
in this way { int,int, Ansi String , int}
You can distribute the DLL, LIBs and CHs, I don'e any trouble,rdonnay wrote: but then would I have the right to distribute your library?
just I would suggest to put a link to my web site to allow users
get the most recent version, source code and examples.
rdonnay wrote: SQLite3 works very similar to Ads when working with a statement cursor. Both
return a numeric handle to a cursor and both have a similar set of functions to
step through the cursor and extract the data.
The diference is that ADS provide a navigable recordset (live or static)
and the sqlite statement must be handled as an iterator.
rdonnay wrote: I am familiar with this technique
in Ads and have written a complete set of higher-level functions that return
data in a format more friendly to Xbase++ programmers, ie in an array or in a
browse.
It would be nice to build this kind of library for SQLite3 and I don't mind
writing the complete set of wrappers provided that I know they will work with
your aliased concept.
Almost all the basic functionality is covered now inside my class, but
maybe will be nice to have all the wrappers as #xtranslates inside the ch
providing the prototypes, there is no problem if you miss a param or pass
the incorrect type.
And also a recordset like you described will be usefull, implementing
pseudo-properties for field names using an access assign method.
For a few thousands recordset my exec_end_ex() method with type
coercing will be enough but as this database is intended primarily
for local usage, will be really powerfull to use
limit/offset/count to navigate large datasets of a lot of
thousand or even million records smouthly.
Regards,
Pablo Botella