[sqlite] sqlite3_free needed when calling sqlite3_result_text ?
Thanks, nice and simple and helpful advice. RBS On 15 Dec 2015 1:45 pm, "Richard Hipp" wrote: > On 12/15/15, Bart Smissaert wrote: > > So I will need to use SQLITE_TRANSIENT then? > > > > Yes. Always use SQLITE_TRANSIENT, at least initially. All the other > options are optimizations. Do not use the other options prematurely > (that is to say, without first trying SQLITE_TRANSIENT and actually > measuring that it presents performance problems) because premature > optimization is the root of all evil > (http://c2.com/cgi/wiki?PrematureOptimization). > -- > D. Richard Hipp > drh at sqlite.org > ___ > sqlite-users mailing list > sqlite-users at mailinglists.sqlite.org > http://mailinglists.sqlite.org/cgi-bin/mailman/listinfo/sqlite-users >
[sqlite] sqlite3_free needed when calling sqlite3_result_text ?
> I have no idea how VB6 implements local variables Pure local variables (declared in the actual procedure) are on the stack as well in VB6. VB6 hides all these kind of details, so I never think about this/deal with this. RBS On Tue, Dec 15, 2015 at 9:33 AM, Hick Gunter wrote: > >Thanks for clarifying that. > > > >> If the pointer refers to memory obtained from sqlite3_malloc > >How do I know that is the case? > >My callback procedure (the procedure that does the actual work, altering > the string) is in a VB6 ActiveX dll, so not in sqlite3.dll > > If you called an sqlite3 API function that says it allocates memory, like > sqlite3_malloc() or sqlite3_mprinft() to produce the string. > > > > >> If the pointer refers to memory obtained from your own allocator > >I suppose this is the case if it is a local variable in this callback > procedure in my VB6 dll. > >In VB6 local variables will go out of scope (cleaned up) once the > procedure is finished. > >So in that case can I use SQLITE_STATIC? > > I guess NO. SQLite needs the value until at least up to the next call to > sqlite3_step(). Calling sqlite3_finalize() or sqlite3_reset() should also > "clear" the "current row". > > > > > >> In all other cases, pass SQLITE_TRANSIENT and, if necessary, dispose > >> of the memory appropriately. > >When is it necessary and what is appropriate? > > You should know where the memory used to store the string in your own code > comes from and how to deal with it. > > As you already stated, a local variable in your callback procedure goes > out of scope automatically. I have no idea how VB6 implements local > variables; in C they are located on the stack, which may be overwritten by > other function calls. > > > On Tue, Dec 15, 2015 at 7:52 AM, Hick Gunter wrote: > > >> The rules are quite simple: > >> > >> If the pointer refers to static memory (preallocated string constants, > >> global variables that you can guarantee won't change while SQLite uses > >> them) use SQLITE_STATIC > >> > >> If the pointer refers to memory obtained from sqlite3_malloc (directly > >> or indirectly e.g. via sqlite3_mprintf() ) and you won't refer to this > >> object again, pass sqlite3_free. > >> > >> If the pointer refers to memory obtained from your own allocator and > >> you won't refer to this object again, pass your own destructor. > >> > >> In all other cases, pass SQLITE_TRANSIENT and, if necessary, dispose > >> of the memory appropriately. > >> > >> SQLITE_TRANSIENT is safe but slow, because SQLite needs to copy the > string. > >> Passing a destructor function is faster but implies a contract to NOT > >> USE THE POINTER AGAIN yourself. > >> SQLITE_STATIC is fastest but implies a contract that the MEMORY WILL > >> NOT CHANGE. > >> > > > ___ > Gunter Hick > Software Engineer > Scientific Games International GmbH > FN 157284 a, HG Wien > Klitschgasse 2-4, A-1130 Vienna, Austria > Tel: +43 1 80100 0 > E-Mail: hick at scigames.at > > This communication (including any attachments) is intended for the use of > the intended recipient(s) only and may contain information that is > confidential, privileged or legally protected. Any unauthorized use or > dissemination of this communication is strictly prohibited. If you have > received this communication in error, please immediately notify the sender > by return e-mail message and delete all copies of the original > communication. Thank you for your cooperation. > > > ___ > sqlite-users mailing list > sqlite-users at mailinglists.sqlite.org > http://mailinglists.sqlite.org/cgi-bin/mailman/listinfo/sqlite-users >
[sqlite] sqlite3_free needed when calling sqlite3_result_text ?
> If you are saying that you plan to obtain the character pointer by calling sqlite3_value_text, then pass that exact pointer to sqlite3_result_text, then I would suggest you use sqlite3_result_value instead But sqlite3_result_value has no option to only set the first X bytes, so it won't allow me to retain only part of the string. Or is there a way to do this with sqlite3_result_value? RBS On Mon, Dec 14, 2015 at 9:00 PM, Igor Tandetnik wrote: > On 12/14/2015 3:09 PM, Bart Smissaert wrote: > >> It could be either a pointer to sqlite3_value_text of sqlite3_value* >> > > No it can't be. sqlite3_result_text takes a char*, not a sqlite3_value* or > a const unsigned char*(*)(sqlite3_value*) > > If you are saying that you plan to obtain the character pointer by calling > sqlite3_value_text, then pass that exact pointer to sqlite3_result_text, > then I would suggest you use sqlite3_result_value instead: it takes > sqlite3_value* directly. If you insist on round-tripping through > sqlite3_value_text, then you must pass SQLITE_TRANSIENT for the last > parameter - the pointer returned by sqlite3_value_text is only guaranteed > to be valid until the custom function returns. > > or it could be a pointer to a locally declared variable >> > > In this case, you would also use SQLITE_TRANSIENT. > > -- > Igor Tandetnik > > ___ > sqlite-users mailing list > sqlite-users at mailinglists.sqlite.org > http://mailinglists.sqlite.org/cgi-bin/mailman/listinfo/sqlite-users >
[sqlite] sqlite3_free needed when calling sqlite3_result_text ?
> like sqlite3_malloc() or sqlite3_mprinft() to produce the string. OK, I won't be doing that. > I guess NO So I will need to use SQLITE_TRANSIENT then? > You should know where the memory used to store the string in your own code comes from and how to deal with it. It will nearly always be a local variable, unless I can avoid this copy and use sqlite3_result_value directly as suggested by Igor. This would be better as it should speed matters up. Not tried this yet. RBS On Tue, Dec 15, 2015 at 9:33 AM, Hick Gunter wrote: > >Thanks for clarifying that. > > > >> If the pointer refers to memory obtained from sqlite3_malloc > >How do I know that is the case? > >My callback procedure (the procedure that does the actual work, altering > the string) is in a VB6 ActiveX dll, so not in sqlite3.dll > > If you called an sqlite3 API function that says it allocates memory, like > sqlite3_malloc() or sqlite3_mprinft() to produce the string. > > > > >> If the pointer refers to memory obtained from your own allocator > >I suppose this is the case if it is a local variable in this callback > procedure in my VB6 dll. > >In VB6 local variables will go out of scope (cleaned up) once the > procedure is finished. > >So in that case can I use SQLITE_STATIC? > > I guess NO. SQLite needs the value until at least up to the next call to > sqlite3_step(). Calling sqlite3_finalize() or sqlite3_reset() should also > "clear" the "current row". > > > > > >> In all other cases, pass SQLITE_TRANSIENT and, if necessary, dispose > >> of the memory appropriately. > >When is it necessary and what is appropriate? > > You should know where the memory used to store the string in your own code > comes from and how to deal with it. > > As you already stated, a local variable in your callback procedure goes > out of scope automatically. I have no idea how VB6 implements local > variables; in C they are located on the stack, which may be overwritten by > other function calls. > > > On Tue, Dec 15, 2015 at 7:52 AM, Hick Gunter wrote: > > >> The rules are quite simple: > >> > >> If the pointer refers to static memory (preallocated string constants, > >> global variables that you can guarantee won't change while SQLite uses > >> them) use SQLITE_STATIC > >> > >> If the pointer refers to memory obtained from sqlite3_malloc (directly > >> or indirectly e.g. via sqlite3_mprintf() ) and you won't refer to this > >> object again, pass sqlite3_free. > >> > >> If the pointer refers to memory obtained from your own allocator and > >> you won't refer to this object again, pass your own destructor. > >> > >> In all other cases, pass SQLITE_TRANSIENT and, if necessary, dispose > >> of the memory appropriately. > >> > >> SQLITE_TRANSIENT is safe but slow, because SQLite needs to copy the > string. > >> Passing a destructor function is faster but implies a contract to NOT > >> USE THE POINTER AGAIN yourself. > >> SQLITE_STATIC is fastest but implies a contract that the MEMORY WILL > >> NOT CHANGE. > >> > > > ___ > Gunter Hick > Software Engineer > Scientific Games International GmbH > FN 157284 a, HG Wien > Klitschgasse 2-4, A-1130 Vienna, Austria > Tel: +43 1 80100 0 > E-Mail: hick at scigames.at > > This communication (including any attachments) is intended for the use of > the intended recipient(s) only and may contain information that is > confidential, privileged or legally protected. Any unauthorized use or > dissemination of this communication is strictly prohibited. If you have > received this communication in error, please immediately notify the sender > by return e-mail message and delete all copies of the original > communication. Thank you for your cooperation. > > > ___ > sqlite-users mailing list > sqlite-users at mailinglists.sqlite.org > http://mailinglists.sqlite.org/cgi-bin/mailman/listinfo/sqlite-users >
[sqlite] sqlite3_free needed when calling sqlite3_result_text ?
>Thanks for clarifying that. > >> If the pointer refers to memory obtained from sqlite3_malloc >How do I know that is the case? >My callback procedure (the procedure that does the actual work, altering the >string) is in a VB6 ActiveX dll, so not in sqlite3.dll If you called an sqlite3 API function that says it allocates memory, like sqlite3_malloc() or sqlite3_mprinft() to produce the string. > >> If the pointer refers to memory obtained from your own allocator >I suppose this is the case if it is a local variable in this callback >procedure in my VB6 dll. >In VB6 local variables will go out of scope (cleaned up) once the procedure is >finished. >So in that case can I use SQLITE_STATIC? I guess NO. SQLite needs the value until at least up to the next call to sqlite3_step(). Calling sqlite3_finalize() or sqlite3_reset() should also "clear" the "current row". > >> In all other cases, pass SQLITE_TRANSIENT and, if necessary, dispose >> of the memory appropriately. >When is it necessary and what is appropriate? You should know where the memory used to store the string in your own code comes from and how to deal with it. As you already stated, a local variable in your callback procedure goes out of scope automatically. I have no idea how VB6 implements local variables; in C they are located on the stack, which may be overwritten by other function calls. On Tue, Dec 15, 2015 at 7:52 AM, Hick Gunter wrote: >> The rules are quite simple: >> >> If the pointer refers to static memory (preallocated string constants, >> global variables that you can guarantee won't change while SQLite uses >> them) use SQLITE_STATIC >> >> If the pointer refers to memory obtained from sqlite3_malloc (directly >> or indirectly e.g. via sqlite3_mprintf() ) and you won't refer to this >> object again, pass sqlite3_free. >> >> If the pointer refers to memory obtained from your own allocator and >> you won't refer to this object again, pass your own destructor. >> >> In all other cases, pass SQLITE_TRANSIENT and, if necessary, dispose >> of the memory appropriately. >> >> SQLITE_TRANSIENT is safe but slow, because SQLite needs to copy the string. >> Passing a destructor function is faster but implies a contract to NOT >> USE THE POINTER AGAIN yourself. >> SQLITE_STATIC is fastest but implies a contract that the MEMORY WILL >> NOT CHANGE. >> ___ Gunter Hick Software Engineer Scientific Games International GmbH FN 157284 a, HG Wien Klitschgasse 2-4, A-1130 Vienna, Austria Tel: +43 1 80100 0 E-Mail: hick at scigames.at This communication (including any attachments) is intended for the use of the intended recipient(s) only and may contain information that is confidential, privileged or legally protected. Any unauthorized use or dissemination of this communication is strictly prohibited. If you have received this communication in error, please immediately notify the sender by return e-mail message and delete all copies of the original communication. Thank you for your cooperation.
[sqlite] sqlite3_free needed when calling sqlite3_result_text ?
Thanks for clarifying that. > If the pointer refers to memory obtained from sqlite3_malloc How do I know that is the case? My callback procedure (the procedure that does the actual work, altering the string) is in a VB6 ActiveX dll, so not in sqlite3.dll > If the pointer refers to memory obtained from your own allocator I suppose this is the case if it is a local variable in this callback procedure in my VB6 dll. In VB6 local variables will go out of scope (cleaned up) once the procedure is finished. So in that case can I use SQLITE_STATIC? > In all other cases, pass SQLITE_TRANSIENT and, if necessary, dispose of the memory appropriately. When is it necessary and what is appropriate? RBS On Tue, Dec 15, 2015 at 7:52 AM, Hick Gunter wrote: > The rules are quite simple: > > If the pointer refers to static memory (preallocated string constants, > global variables that you can guarantee won't change while SQLite uses > them) use SQLITE_STATIC > > If the pointer refers to memory obtained from sqlite3_malloc (directly or > indirectly e.g. via sqlite3_mprintf() ) and you won't refer to this object > again, pass sqlite3_free. > > If the pointer refers to memory obtained from your own allocator and you > won't refer to this object again, pass your own destructor. > > In all other cases, pass SQLITE_TRANSIENT and, if necessary, dispose of > the memory appropriately. > > SQLITE_TRANSIENT is safe but slow, because SQLite needs to copy the string. > Passing a destructor function is faster but implies a contract to NOT USE > THE POINTER AGAIN yourself. > SQLITE_STATIC is fastest but implies a contract that the MEMORY WILL NOT > CHANGE. > > -Urspr?ngliche Nachricht- > Von: sqlite-users-bounces at mailinglists.sqlite.org [mailto: > sqlite-users-bounces at mailinglists.sqlite.org] Im Auftrag von Bart > Smissaert > Gesendet: Montag, 14. Dezember 2015 20:22 > An: General Discussion of SQLite Database > Betreff: [sqlite] sqlite3_free needed when calling sqlite3_result_text ? > > Not sure if I need to call sqlite3_free after running sqlite3_result_text > or if sqlite3_free should be an argument (last one) in sqlite3_result_text. > Currently I am using SQLITE_TRANSIENT as the last argument, so that is > after the number of bytes, but have feeling I might be doing this wrong. > Thanks for any advice. > > RBS > ___ > sqlite-users mailing list > sqlite-users at mailinglists.sqlite.org > http://mailinglists.sqlite.org/cgi-bin/mailman/listinfo/sqlite-users > > > ___ > Gunter Hick > Software Engineer > Scientific Games International GmbH > FN 157284 a, HG Wien > Klitschgasse 2-4, A-1130 Vienna, Austria > Tel: +43 1 80100 0 > E-Mail: hick at scigames.at > > This communication (including any attachments) is intended for the use of > the intended recipient(s) only and may contain information that is > confidential, privileged or legally protected. Any unauthorized use or > dissemination of this communication is strictly prohibited. If you have > received this communication in error, please immediately notify the sender > by return e-mail message and delete all copies of the original > communication. Thank you for your cooperation. > > > ___ > sqlite-users mailing list > sqlite-users at mailinglists.sqlite.org > http://mailinglists.sqlite.org/cgi-bin/mailman/listinfo/sqlite-users >
[sqlite] sqlite3_free needed when calling sqlite3_result_text ?
> but the string "abc" is not 4 bytes long, no matter how you count. Yes, sorry to cause confusion there, the -2 got in there as in my testing setup there was always a space before the string to find. This is not really to do with the problem I am seeing though. RBS On Tue, Dec 15, 2015 at 1:22 AM, Igor Tandetnik wrote: > On 12/14/2015 7:42 PM, Bart Smissaert wrote: > >> Yes, str and str2 are Unicode string, 2 bytes per character. >> lPos counts per character, not byte, so if the string in the database is >> abcde and I want to find the first position >> of d in that string then lPos will be 4. >> > > ... and then you pass (lPos-2)*2 == 4 - but the string "abc" is not 4 > bytes long, no matter how you count. > > You are converting in one direction (SQLite to VB), but not in the other >>> >> I thought SQLite would handle VB Unicode strings to UTF8 strings >> > > It would, if you use the correct API function, so that SQLite knows that > the string is in fact Unicode. > > -- > Igor Tandetnik > > ___ > sqlite-users mailing list > sqlite-users at mailinglists.sqlite.org > http://mailinglists.sqlite.org/cgi-bin/mailman/listinfo/sqlite-users >
[sqlite] sqlite3_free needed when calling sqlite3_result_text ?
On 12/15/15, Bart Smissaert wrote: > So I will need to use SQLITE_TRANSIENT then? > Yes. Always use SQLITE_TRANSIENT, at least initially. All the other options are optimizations. Do not use the other options prematurely (that is to say, without first trying SQLITE_TRANSIENT and actually measuring that it presents performance problems) because premature optimization is the root of all evil (http://c2.com/cgi/wiki?PrematureOptimization). -- D. Richard Hipp drh at sqlite.org
[sqlite] sqlite3_free needed when calling sqlite3_result_text ?
The rules are quite simple: If the pointer refers to static memory (preallocated string constants, global variables that you can guarantee won't change while SQLite uses them) use SQLITE_STATIC If the pointer refers to memory obtained from sqlite3_malloc (directly or indirectly e.g. via sqlite3_mprintf() ) and you won't refer to this object again, pass sqlite3_free. If the pointer refers to memory obtained from your own allocator and you won't refer to this object again, pass your own destructor. In all other cases, pass SQLITE_TRANSIENT and, if necessary, dispose of the memory appropriately. SQLITE_TRANSIENT is safe but slow, because SQLite needs to copy the string. Passing a destructor function is faster but implies a contract to NOT USE THE POINTER AGAIN yourself. SQLITE_STATIC is fastest but implies a contract that the MEMORY WILL NOT CHANGE. -Urspr?ngliche Nachricht- Von: sqlite-users-bounces at mailinglists.sqlite.org [mailto:sqlite-users-bounces at mailinglists.sqlite.org] Im Auftrag von Bart Smissaert Gesendet: Montag, 14. Dezember 2015 20:22 An: General Discussion of SQLite Database Betreff: [sqlite] sqlite3_free needed when calling sqlite3_result_text ? Not sure if I need to call sqlite3_free after running sqlite3_result_text or if sqlite3_free should be an argument (last one) in sqlite3_result_text. Currently I am using SQLITE_TRANSIENT as the last argument, so that is after the number of bytes, but have feeling I might be doing this wrong. Thanks for any advice. RBS ___ sqlite-users mailing list sqlite-users at mailinglists.sqlite.org http://mailinglists.sqlite.org/cgi-bin/mailman/listinfo/sqlite-users ___ Gunter Hick Software Engineer Scientific Games International GmbH FN 157284 a, HG Wien Klitschgasse 2-4, A-1130 Vienna, Austria Tel: +43 1 80100 0 E-Mail: hick at scigames.at This communication (including any attachments) is intended for the use of the intended recipient(s) only and may contain information that is confidential, privileged or legally protected. Any unauthorized use or dissemination of this communication is strictly prohibited. If you have received this communication in error, please immediately notify the sender by return e-mail message and delete all copies of the original communication. Thank you for your cooperation.
[sqlite] sqlite3_free needed when calling sqlite3_result_text ?
Maybe I shouldn't make Unicode strings but keep it all in UTF8. Not sure though how to get the position then of string2 in string1, lPos. RBS On Tue, Dec 15, 2015 at 12:42 AM, Bart Smissaert wrote: > Yes, str and str2 are Unicode string, 2 bytes per character. > lPos counts per character, not byte, so if the string in the database is > abcde and I want to find the first position > of d in that string then lPos will be 4. > > > You are converting in one direction (SQLite to VB), but not in the other > I thought SQLite would handle VB Unicode strings to UTF8 strings, but I > think you may be onto something there, > because if I move VB Unicode strings to SQLite I do sqlite3_bind_text16 > and I understand sqlite3_result_text is very > similar to sqlite3_bind_text. So, it makes sense I need > sqlite3_result_text16 instead. > > Will do some further testing. > > RBS > > > > > On Tue, Dec 15, 2015 at 12:22 AM, Igor Tandetnik > wrote: > >> On 12/14/2015 5:46 PM, Bart Smissaert wrote: >> >>> OK, thanks, will have to study this carefully. >>> So, if I understand you well then the way I do it now I would need >>> sqlite3_free? >>> >> >> First, I don't know how you do it now - you've never described that. >> Second, I have not ever said you needed sqlite3_free; nothing in your >> description of the problem so far suggests you need it. >> >> 'string not found, so return original field string >>> '- >>> 140 If lPos = 0 Then >>> 150 sqlite3_result_value lPtr_ObjContext, lPtr1 >>> 160 Exit Sub >>> 170 End If >>> 180 sqlite3_result_text lPtr_ObjContext, StrPtr(str), _ >>> (lPos - 2) * 2, SQLITE_TRANSIENT >>> >> >> To the extent I understand what's going on (I'm not really familiar with >> VB, so I'm taking and educated guess for the most part), the memory >> management part looks OK to me. >> >> However, I have doubts about encoding. Comments seem to suggest str >> points to a Unicode string; also the fact that you multiply lPos by 2. But >> sqlite3_result_text expects UTF-8 string. You are converting in one >> direction (SQLite to VB), but not in the other, as far as I can tell. I >> suspect you need sqlite3_result_text16 instead. >> >> Also lPos-2 looks wrong. Can't the substring be found at lPos == 1 ? >> >> -- >> Igor Tandetnik >> >> ___ >> sqlite-users mailing list >> sqlite-users at mailinglists.sqlite.org >> http://mailinglists.sqlite.org/cgi-bin/mailman/listinfo/sqlite-users >> > >
[sqlite] sqlite3_free needed when calling sqlite3_result_text ?
Yes, str and str2 are Unicode string, 2 bytes per character. lPos counts per character, not byte, so if the string in the database is abcde and I want to find the first position of d in that string then lPos will be 4. > You are converting in one direction (SQLite to VB), but not in the other I thought SQLite would handle VB Unicode strings to UTF8 strings, but I think you may be onto something there, because if I move VB Unicode strings to SQLite I do sqlite3_bind_text16 and I understand sqlite3_result_text is very similar to sqlite3_bind_text. So, it makes sense I need sqlite3_result_text16 instead. Will do some further testing. RBS On Tue, Dec 15, 2015 at 12:22 AM, Igor Tandetnik wrote: > On 12/14/2015 5:46 PM, Bart Smissaert wrote: > >> OK, thanks, will have to study this carefully. >> So, if I understand you well then the way I do it now I would need >> sqlite3_free? >> > > First, I don't know how you do it now - you've never described that. > Second, I have not ever said you needed sqlite3_free; nothing in your > description of the problem so far suggests you need it. > > 'string not found, so return original field string >> '- >> 140 If lPos = 0 Then >> 150 sqlite3_result_value lPtr_ObjContext, lPtr1 >> 160 Exit Sub >> 170 End If >> 180 sqlite3_result_text lPtr_ObjContext, StrPtr(str), _ >> (lPos - 2) * 2, SQLITE_TRANSIENT >> > > To the extent I understand what's going on (I'm not really familiar with > VB, so I'm taking and educated guess for the most part), the memory > management part looks OK to me. > > However, I have doubts about encoding. Comments seem to suggest str points > to a Unicode string; also the fact that you multiply lPos by 2. But > sqlite3_result_text expects UTF-8 string. You are converting in one > direction (SQLite to VB), but not in the other, as far as I can tell. I > suspect you need sqlite3_result_text16 instead. > > Also lPos-2 looks wrong. Can't the substring be found at lPos == 1 ? > > -- > Igor Tandetnik > > ___ > sqlite-users mailing list > sqlite-users at mailinglists.sqlite.org > http://mailinglists.sqlite.org/cgi-bin/mailman/listinfo/sqlite-users >
[sqlite] sqlite3_free needed when calling sqlite3_result_text ?
OK, thanks, will have to study this carefully. So, if I understand you well then the way I do it now I would need sqlite3_free? Not sure it is helpful, but this is the callback procedure as I have it. It will find a specified string (second argument in SQL) in the supplied field value (first argument) and produce a string as in the first argument string, but leaving out all starting at the start of the second argument string. I know all this can be done quite simple with the built-in function substr and instr and that is probably faster, but I just use this as test code: Sub ClearStartAtStringX(ByVal lPtr_ObjContext As Long, _ ByVal lArgCount As Long, _ ByVal lPtr_ObjSQLite3_Value As Long) Dim lPtr1 As Long Dim lPtr2 As Long Dim lPtr3 As Long Dim lPtr4 As Long Dim str As String Dim str2 As String Dim lPos As Long Dim lBytes As Long 'field value to alter ' 10 lPtr1 = MemLong(lPtr_ObjSQLite3_Value) 'copy pointer 20 lPtr2 = sqlite3_value_text(lPtr1) 30 lBytes = sqlite3_value_bytes(lPtr1) 40 If lBytes = 0 Then 50sqlite3_result_null lPtr_ObjContext 60Exit Sub 70 End If 'produce normal VB Unicode string 80 str = cSQL.PointerToString(lPtr2, CP_UTF8, lBytes, lBytes) 'clear after finding this string '--- 90 lPtr3 = MemLong(lPtr_ObjSQLite3_Value + 4) 'copy pointer 100 lPtr4 = sqlite3_value_text(lPtr3) 110 lBytes = sqlite3_value_bytes(lPtr3) 'produce normal VB Unicode string 120 str2 = cSQL.PointerToString(lPtr4, CP_UTF8, lBytes, lBytes) 130 lPos = InStr(1, str, str2, vbBinaryCompare) 'VB instr function 'string not found, so return original field string '- 140 If lPos = 0 Then 150 sqlite3_result_value lPtr_ObjContext, lPtr1 160 Exit Sub 170 End If 180 sqlite3_result_text lPtr_ObjContext, StrPtr(str), _ (lPos - 2) * 2, SQLITE_TRANSIENT End Sub RBS On Mon, Dec 14, 2015 at 9:00 PM, Igor Tandetnik wrote: > On 12/14/2015 3:09 PM, Bart Smissaert wrote: > >> It could be either a pointer to sqlite3_value_text of sqlite3_value* >> > > No it can't be. sqlite3_result_text takes a char*, not a sqlite3_value* or > a const unsigned char*(*)(sqlite3_value*) > > If you are saying that you plan to obtain the character pointer by calling > sqlite3_value_text, then pass that exact pointer to sqlite3_result_text, > then I would suggest you use sqlite3_result_value instead: it takes > sqlite3_value* directly. If you insist on round-tripping through > sqlite3_value_text, then you must pass SQLITE_TRANSIENT for the last > parameter - the pointer returned by sqlite3_value_text is only guaranteed > to be valid until the custom function returns. > > or it could be a pointer to a locally declared variable >> > > In this case, you would also use SQLITE_TRANSIENT. > > -- > Igor Tandetnik > > ___ > sqlite-users mailing list > sqlite-users at mailinglists.sqlite.org > http://mailinglists.sqlite.org/cgi-bin/mailman/listinfo/sqlite-users >
[sqlite] sqlite3_free needed when calling sqlite3_result_text ?
On 12/14/2015 7:42 PM, Bart Smissaert wrote: > Yes, str and str2 are Unicode string, 2 bytes per character. > lPos counts per character, not byte, so if the string in the database is > abcde and I want to find the first position > of d in that string then lPos will be 4. ... and then you pass (lPos-2)*2 == 4 - but the string "abc" is not 4 bytes long, no matter how you count. >> You are converting in one direction (SQLite to VB), but not in the other > I thought SQLite would handle VB Unicode strings to UTF8 strings It would, if you use the correct API function, so that SQLite knows that the string is in fact Unicode. -- Igor Tandetnik
[sqlite] sqlite3_free needed when calling sqlite3_result_text ?
It could be either a pointer to sqlite3_value_text of sqlite3_value* or it could be a pointer to a locally declared variable, so that is declared in a procedure in a VB6 ActiveX dll. Do I need to run sqlite3_free in the first case and not in the second case? If do need to run it how do I do it? As an argument in sqlite3_result_text or after running sqlite3_result_text? Do I need to run it with a pointer? RBS On Mon, Dec 14, 2015 at 7:27 PM, Igor Tandetnik wrote: > On 12/14/2015 2:21 PM, Bart Smissaert wrote: > >> Not sure if I need to call sqlite3_free after running sqlite3_result_text >> or >> if sqlite3_free should be an argument (last one) in sqlite3_result_text. >> > > That depends on how the memory was obtained that the second argument > points to. > -- > Igor Tandetnik > > ___ > sqlite-users mailing list > sqlite-users at mailinglists.sqlite.org > http://mailinglists.sqlite.org/cgi-bin/mailman/listinfo/sqlite-users >
[sqlite] sqlite3_free needed when calling sqlite3_result_text ?
On 12/14/2015 5:46 PM, Bart Smissaert wrote: > OK, thanks, will have to study this carefully. > So, if I understand you well then the way I do it now I would need > sqlite3_free? First, I don't know how you do it now - you've never described that. Second, I have not ever said you needed sqlite3_free; nothing in your description of the problem so far suggests you need it. > 'string not found, so return original field string > '- > 140 If lPos = 0 Then > 150 sqlite3_result_value lPtr_ObjContext, lPtr1 > 160 Exit Sub > 170 End If > 180 sqlite3_result_text lPtr_ObjContext, StrPtr(str), _ > (lPos - 2) * 2, SQLITE_TRANSIENT To the extent I understand what's going on (I'm not really familiar with VB, so I'm taking and educated guess for the most part), the memory management part looks OK to me. However, I have doubts about encoding. Comments seem to suggest str points to a Unicode string; also the fact that you multiply lPos by 2. But sqlite3_result_text expects UTF-8 string. You are converting in one direction (SQLite to VB), but not in the other, as far as I can tell. I suspect you need sqlite3_result_text16 instead. Also lPos-2 looks wrong. Can't the substring be found at lPos == 1 ? -- Igor Tandetnik
[sqlite] sqlite3_free needed when calling sqlite3_result_text ?
Not sure if I need to call sqlite3_free after running sqlite3_result_text or if sqlite3_free should be an argument (last one) in sqlite3_result_text. Currently I am using SQLITE_TRANSIENT as the last argument, so that is after the number of bytes, but have feeling I might be doing this wrong. Thanks for any advice. RBS
[sqlite] sqlite3_free needed when calling sqlite3_result_text ?
On 12/14/2015 3:09 PM, Bart Smissaert wrote: > It could be either a pointer to sqlite3_value_text of sqlite3_value* No it can't be. sqlite3_result_text takes a char*, not a sqlite3_value* or a const unsigned char*(*)(sqlite3_value*) If you are saying that you plan to obtain the character pointer by calling sqlite3_value_text, then pass that exact pointer to sqlite3_result_text, then I would suggest you use sqlite3_result_value instead: it takes sqlite3_value* directly. If you insist on round-tripping through sqlite3_value_text, then you must pass SQLITE_TRANSIENT for the last parameter - the pointer returned by sqlite3_value_text is only guaranteed to be valid until the custom function returns. > or it could be a pointer to a locally declared variable In this case, you would also use SQLITE_TRANSIENT. -- Igor Tandetnik
[sqlite] sqlite3_free needed when calling sqlite3_result_text ?
On 12/14/2015 2:21 PM, Bart Smissaert wrote: > Not sure if I need to call sqlite3_free after running sqlite3_result_text or > if sqlite3_free should be an argument (last one) in sqlite3_result_text. That depends on how the memory was obtained that the second argument points to. -- Igor Tandetnik