Calling C from V

Example

  1. #flag -lsqlite3
  2. #include "sqlite3.h"
  3. // See also the example from https://www.sqlite.org/quickstart.html
  4. struct C.sqlite3 {
  5. }
  6. struct C.sqlite3_stmt {
  7. }
  8. type FnSqlite3Callback = fn (voidptr, int, &&char, &&char) int
  9. fn C.sqlite3_open(&char, &&C.sqlite3) int
  10. fn C.sqlite3_close(&C.sqlite3) int
  11. fn C.sqlite3_column_int(stmt &C.sqlite3_stmt, n int) int
  12. // ... you can also just define the type of parameter and leave out the C. prefix
  13. fn C.sqlite3_prepare_v2(&C.sqlite3, &char, int, &&C.sqlite3_stmt, &&char) int
  14. fn C.sqlite3_step(&C.sqlite3_stmt)
  15. fn C.sqlite3_finalize(&C.sqlite3_stmt)
  16. fn C.sqlite3_exec(db &C.sqlite3, sql &char, cb FnSqlite3Callback, cb_arg voidptr, emsg &&char) int
  17. fn C.sqlite3_free(voidptr)
  18. fn my_callback(arg voidptr, howmany int, cvalues &&char, cnames &&char) int {
  19. unsafe {
  20. for i in 0 .. howmany {
  21. print('| ${cstring_to_vstring(cnames[i])}: ${cstring_to_vstring(cvalues[i]):20} ')
  22. }
  23. }
  24. println('|')
  25. return 0
  26. }
  27. fn main() {
  28. db := &C.sqlite3(0) // this means `sqlite3* db = 0`
  29. // passing a string literal to a C function call results in a C string, not a V string
  30. C.sqlite3_open(c'users.db', &db)
  31. // C.sqlite3_open(db_path.str, &db)
  32. query := 'select count(*) from users'
  33. stmt := &C.sqlite3_stmt(0)
  34. // NB: you can also use the `.str` field of a V string,
  35. // to get its C style zero terminated representation
  36. C.sqlite3_prepare_v2(db, &char(query.str), -1, &stmt, 0)
  37. C.sqlite3_step(stmt)
  38. nr_users := C.sqlite3_column_int(stmt, 0)
  39. C.sqlite3_finalize(stmt)
  40. println('There are $nr_users users in the database.')
  41. //
  42. error_msg := &char(0)
  43. query_all_users := 'select * from users'
  44. rc := C.sqlite3_exec(db, &char(query_all_users.str), my_callback, voidptr(7), &error_msg)
  45. if rc != C.SQLITE_OK {
  46. eprintln(unsafe { cstring_to_vstring(error_msg) })
  47. C.sqlite3_free(error_msg)
  48. }
  49. C.sqlite3_close(db)
  50. }