Upgrade to Pro — share decks privately, control downloads, hide ads and more …

The First Step for Building Groonga Bindings with Golang

The First Step for Building Groonga Bindings with Golang

Goで体験
はじめての
Groonga bindingづくり

全文検索エンジンGroonga勉強会@札幌
2014-03-29 札幌市民ホール 第4会議室

Yoji Shidara

March 29, 2014
Tweet

More Decks by Yoji Shidara

Other Decks in Technology

Transcript

  1. Groonga2013 Powered by Rabbit 2.1.2 Groonga libgroonga gqtp _ `a

    bcd e fBg e fh Bij  kQ groonga l API HTTP SQL CLI ,PIFJ4VUP l(SPPOHB଒zIUUQTMJEFSBCCJUTIPDLFSPSHBVUIPSTLPVHSPPOHBOJHIU$$#:4"
  2. Groonga2013 Powered by Rabbit 2.1.2 Groonga libgroonga gqtp _ `a

    bcd e fBg e fh Bij  kQ groonga l API HTTP SQL CLI ,PIFJ4VUP l(SPPOHB଒zIUUQTMJEFSBCCJUTIPDLFSPSHBVUIPSTLPVHSPPOHBOJHIU$$#:4" ͔͜͜Β
 ࢖͏
  3. Groonga2013 Powered by Rabbit 2.1.2 Groonga libgroonga gqtp _ `a

    bcd e fBg e fh Bij  kQ groonga l API HTTP SQL CLI ,PIFJ4VUP l(SPPOHB଒zIUUQTMJEFSBCCJUTIPDLFSPSHBVUIPSTLPVHSPPOHBOJHIU$$#:4" ࠓͷ͸
 $-*
  4. ͜Θ͘ͳ͍ w ࢝·ΓͱऴΘΓ
 HSO@JOJU HSO@pO  w ίϯςΩετ HSO@DUY ͷ࡞੒ͱഁغ


    HSO@DUY@JOJU HSO@DUY@pO  w σʔλϕʔεͷ࡞੒ɾΦʔϓϯͱΫϩʔζ
 HSO@EC@DSFBUF HSO@EC@PQFO HSO@PCK@DMPTF  w ίϚϯυͷૹ৴ͱड৴
 HSO@DUY@TFOE HSO@DUY@SFDW
  5. ' ' ( ( ) ) * * # #

    , , file file 349 lines (221 sloc) 349 lines (221 sloc) 12.16 kb 12.16 kb 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 =,groonga,C,API,ϚχϡΞϧ groongaͷCݴޠAPI͸ɺ1)ڞ௨APIɺ2)QL,APIɺ3)DB,APIɺ4)௿ϨϕϧAPIͷ4छʹେผ͞ΕΔɻ ڞ௨API͸ଞͷશͯͷAPIͱ૊Έ߹Θͤͯڞ௨ʹ࢖༻͞ΕΔɻ࢒Γͷ3छͷAPI͸֊૚ߏ଄Λͳ͍ͯ͠Δɻ QL,API͸࠷΋্ҐʹҐஔ͠ɺquery,languageΛհͯ͠σʔλετΞΛૢ࡞͢ΔػೳΛఏڙ͢Δɻ DB,API͸QL,APIͷԼҐʹҐஔ͠ɺσʔλετΞΛߏ੒͢Δ֤ΦϒδΣΫτΛૢ࡞͢ΔػೳΛఏڙ͢Δɻ ௿ϨϕϧAPI͸DB,APIͷ͞ΒʹԼҐʹҐஔ͠ɺσʔλΦϒδΣΫτͷߏ੒ཁૉΛ௚઀ૢ࡞͢ΔػೳΛఏڙ͢Δɻ =,ڞ௨API ==,grn_init :NAME ,,grn_init,,grn_fin,I,groongaϥΠϒϥϦΛॳظԽ/ղ์͢Δ :SYNOPSIS ,((',')) ,,#include,<groonga/groonga.h> ,,grn_rc,grn_init(void); ,,grn_rc,grn_fin(void); :DESCRIPTION ,,grn_init()͸ɺlibgroonga͕ඞཁͱ͢ΔࢿݯͷॳظԽΛߦ͏ɻlibgroongaΛ࢖༻͢ΔϓϩάϥϜ͸ଞͷgroonga,APIؔ਺Λݺͼग़͢લʹҰ౓͚ͩgrn_init()Λݺͼग़͞ͳ͚ ,,grn_fin()͸libgroonga͕࢖༻͢ΔࢿݯΛղ์͢Δɻgrn_fin()࣮ߦޙʹgroonga,APIؔ਺Λ࣮ߦͯ͠͸ͳΒͳ͍ɻ :RETURN,VALUE ,,੒ޭͨ͠৔߹͸GRN_SUCCESSΛฦ͢ɻ ,,grn_init()͸ɺࢿݯͷ֬อʹࣦഊͨ͠৔߹ʹGRN_NO_MEMORY_AVAILABLEΛฦ͢ɻ :NOTES ,,grn_init(),,grn_fin()͸ϦΤϯτϥϯτͰ͸ͳ͍ɻͦͷଞͷgroongaͷC,APIؔ਺͸શͯϦΤϯτϥϯτͰ͋Δɻ - - - Open Open Open Edit Edit Edit Raw Raw Blame Blame History History Delete Delete IUUQTHJUIVCDPNHSPPOHBHSPPOHBCMPCNBTUFSEPD"1*SE
  6. package main ! /* #cgo pkg-config: groonga #include <groonga.h> */

    import "C" ! func main() { C.grn_init() // TODO error handling defer C.grn_fin() // TODO error handling } NBJO ͕ऴΘΔͱ͖ʹ࣮ߦ͢Δ
  7. 39 40 41 42 43 44 45 46 47 48

    49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 ==,grn_ctx_init :NAME ,,grn_ctx_init,,grn_ctx_fin,I,grn_ctxߏ଄ମΛॳظԽ/ղ์͢Δ :SYNOPSIS ,((',')) ,,#include,<groonga/groonga.h> ,,grn_rc,grn_ctx_init(grn_ctx,*ctx,,int,flags,,grn_encoding,encoding); ,,grn_rc,grn_ctx_fin(grn_ctx,*ctx); :DESCRIPTION ,,grn_ctx͸ɺ1)Τϥʔ৘ใͷ௨஌ɺ2)API಺෦Ͱ࢖༻͢ΔϝϞϦͷ؅ཧɺ3)ΫΤϦݴޠॲཧܥͷ؅ཧͷͨΊʹ࢖༻͞ΕΔߏ଄ମͰ͋Δɻ΄ͱΜͲͷAPIؔ਺͸ୈҰҾ਺ʹgrn_ct ,,,typedef,struct,_grn_ctx,grn_ctx; ,,,struct,_grn_ctx,{ ,,,,,grn_rc,rc;,,,,,,,,,,,,,,,,,,,,,,,/*,࠷ޙʹ࣮ߦͨ͠APIͷऴྃίʔυ,*/ ,,,,,int,flags;,,,,,,,,,,,,,,,,,,,,,,,/*,಺෦ॲཧ༻,*/ ,,,,,grn_encoding,encoding;,,,,,,,,,,,/*,σϑΥϧτͷจࣈΤϯίʔσΟϯά,*/ ,,,,,unsigned,char,ntrace;,,,,,,,,,,,,/*,όοΫτϨʔεͷ਺,*/ ,,,,,unsigned,char,errlvl;,,,,,,,,,,,,/*,࠷ޙʹൃੜͨ͠ΤϥʔͷϨϕϧ,*/ ,,,,,unsigned,char,stat;,,,,,,,,,,,,,,/*,಺෦ॲཧ༻,*/ ,,,,,unsigned,int,seqno;,,,,,,,,,,,,,,/*,಺෦ॲཧ༻,*/ ,,,,,unsigned,int,subno;,,,,,,,,,,,,,,/*,಺෦ॲཧ༻,*/ ,,,,,unsigned,int,seqno2;,,,,,,,,,,,,,/*,಺෦ॲཧ༻,*/ ,,,,,unsigned,int,errline;,,,,,,,,,,,,/*,Τϥʔ͕ൃੜͨ͠Օॴͷߦ൪߸,*/ ,,,,,grn_ctx,*prev;,,,,,,,,,,,,,,,,,,,/*,಺෦ॲཧ༻,*/ ,,,,,grn_ctx,*next;,,,,,,,,,,,,,,,,,,,/*,಺෦ॲཧ༻,*/ ,,,,,const,char,*errfile;,,,,,,,,,,,,,/*,Τϥʔ͕ൃੜͨ͠ιʔεϑΝΠϧ໊,*/ ,,,,,const,char,*errfunc;,,,,,,,,,,,,,/*,Τϥʔ͕ൃੜͨؔ͠਺໊,*/ ,,,,,struct,_grn_ctx_impl,*impl;,,,,,,/*,಺෦ॲཧ༻,*/ ,,,,,void,*trace[16];,,,,,,,,,,,,,,,,,/*,όοΫτϨʔεϙΠϯλ഑ྻ,*/ ,,,,,char,errbuf[GRN_CTX_MSGSIZE];,,,,/*,࠷ޙʹൃੜͨ͠Τϥʔʹؔ͢Δϝοηʔδ,*/ ,,,}; ,,grn_ctxߏ଄ମ͸APIͰ࢖༻͢Δલʹgrn_ctx_init()ͰॳظԽ͠ͳ͚Ε͹ͳΒͳ͍ɻॳظԽ͢Δgrn_ctxߏ଄ମ΁ͷϙΠϯλΛ'ctx'ʹࢦఆ͢Δɻ'flags'ʹGRN_CTX_USE_QL IUUQTHJUIVCDPNHSPPOHBHSPPOHBCMPCNBTUFSEPD"1*SE
  8. package main ! /* #cgo pkg-config: groonga #include <groonga.h> #include

    <stdlib.h> */ import "C" ! func main() { C.grn_init() // TODO error handling defer C.grn_fin() // TODO error handling ! ctx := C.grn_ctx_open(0) defer C.grn_ctx_fin(ctx) // TODO error handling } qBHT͸ͱΓ͋͑ͣͰ
  9. It is used for specifying options for grn_db_create(). char **grn_db_create_optarg.builtin_type_names

    ૊ΈࠐΈܕͷ໊લͱͳΔnulऴ୺จࣈྻͷ഑ྻΛࢦఆ͢Δɻ int grn_db_create_optarg.n_builtin_type_names n_builtin_type_namesʹ͸ɺoptarg.builtin_type_namesͰࢦఆ͢Δจࣈྻͷ਺Λ ࢦఆ͢Δɻ഑ ྻͷoffset͸enumܕgrn_builtin_typeͷ஋ʹରԠ͢Δɻ grn_obj *grn_db_create(grn_ctx *ctx, const char *path, grn_db_create_optarg *optarg) ৽ͨͳdbΛ࡞੒͠·͢ɻ ύ ϥ ϝ λ: ctx -- ॳظԽࡁΈͷ grn_ctx Λࢦఆ͠·͢ɻ path -- ࡞੒͢ΔdbΛ֨ೲ͢ΔϑΝΠϧύεΛࢦఆ͠·͢ɻNULLͳΒtemporary db ͱͳΓ·͢ɻNULLҎ֎ͷύεΛࢦఆͨ͠৔߹͸persistent dbͱͳΓ·͢ɻ optarg -- Currently, it is not used. It is just ignored. ࡞੒͢Δdbͷ૊ΈࠐΈܕͷ໊લΛมߋ͢Δ࣌ʹࢦఆ͠·͢ɻ optarg.builtin_type_namesʹ͸ɺ૊ΈࠐΈܕͷ໊લͱͳΔnullऴ୺จࣈྻͷ഑ྻΛࢦ ఆ͠·͢ɻoptarg.n_builtin_type_namesʹ͸ɺoptarg.builtin_type_namesͰࢦఆ͢Δจ ࣈྻͷ਺Λࢦఆ͠·͢ɻ഑ྻͷoffset͸enumܕgrn_builtin_typeͷ஋ʹରԠ͠·͢ɻ grn_obj *grn_db_open(grn_ctx *ctx, const char *path) طଘͷdbΛ։͖·͢ɻ ύϥϝλ: path -- ։͜͏ͱ͢ΔdbΛ֨ೲ͢ΔϑΝΠϧύεΛࢦఆ͠·͢ɻ void grn_db_touch(grn_ctx *ctx, grn_obj *db) dbͷ಺༰ͷ࠷ऴߋ৽࣌ࠁΛݱࡏ࣌ࠁʹ͠·͢ɻ ࠷ऴߋ৽࣌ࠁ͸Ωϟογϡ͕༗ޮ͔Ͳ͏͔ͷ൑அͳͲʹར༻͞Ε·͢ɻ ύϥϝλ: db -- ಺༰͕มߋ͞ΕͨdbΛࢦఆ͠·͢ɻ grn_obj *grn_obj_db(grn_ctx *ctx, grn_obj *obj) objͷଐ͢ΔdbΛฦ͠·͢ɻ ύϥϝλ: obj -- ର৅objectΛࢦఆ͠·͢ɻ ϞδϡʔϧɺΫϥεɺ·ͨ͸ؔ਺໊ Λೖྗ͍ͯͩ͘͠͞ IUUQHSPPOHBPSHKBEPDTSFGFSFODFBQJHSO@ECIUNM طଘͷ%#Λ։͘ͱ͖͸͜Ε ͜ΕΛ࢖͍·͢
  10. package main ! /* #cgo pkg-config: groonga #include <groonga.h> #include

    <stdlib.h> */ import "C" import "unsafe" ! func main() { C.grn_init() // TODO error handling defer C.grn_fin() // TODO error handling ! ctx := C.grn_ctx_open(0) defer C.grn_ctx_fin(ctx) // TODO error handling ! dbPath := "db" cDbPath := C.CString(dbPath) defer C.free(unsafe.Pointer(cDbPath)) db := C.grn_db_create(ctx, cDbPath, nil) if db == nil { log.Fatal("[grn_db_create] Failed to create DB") } defer C.grn_obj_close(ctx, db) } EC1BUIΛ$ͷจࣈྻʹ͠·͢
  11. import "fmt" func main() { f := C.intFunc(C.fortytwo) fmt.Println(int(C.bridge_int_func(f))) //

    Output: 42 } In C, a function argument written as a fixed size array actually requires a pointer to the first element of the array. C compilers are aware of this calling convention and adjust the call accordingly, but Go cannot. In Go, you must pass the pointer to the first element explicitly: C.f(&x[0]). A few special functions convert between Go and C types by making copies of the data. In pseudo-Go definitions: // Go string to C string // The C string is allocated in the C heap using malloc. // It is the caller's responsibility to arrange for it to be // freed, such as by calling C.free (be sure to include stdlib.h // if C.free is needed). func C.CString(string) *C.char // C string to Go string func C.GoString(*C.char) string // C string, length to Go string func C.GoStringN(*C.char, C.int) string // C pointer, length to Go []byte func C.GoBytes(unsafe.Pointer, C.int) []byte C references to Go Go functions can be exported for use by C code in the following way: //export MyFunction func MyFunction(arg1, arg2 int, arg3 string) int64 {...} //export MyFunction2 func MyFunction2(arg1, arg2 int, arg3 string) (int64, *C.char) {...} IUUQHPMBOHPSHDNEDHP
  12. 265 266 267 268 269 270 271 272 273 274

    275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 290 291 292 293 294 295 296 297 298 299 300 301 302 303 304 305 306 307 ==,grn_ctx_send :NAME ,,grn_ctx_send,I,͓͘Δ :SYNOPSIS ,((',')) ,,#include,<groonga/groonga.h> ,,unsigned,grn_ctx_send(grn_ctx,*ctx,,char,*str,,unsigned,int,str_len,,int,flags); :DESCRIPTION ,,͓͘Δ ==,grn_ctx_recv :NAME ,,grn_ctx_recv,I,͏͚ͱΔ :SYNOPSIS ,((',')) ,,#include,<groonga/groonga.h> ,,unsigned,grn_ctx_recv(grn_ctx,*ctx,,char,**str,,unsigned,int,*str_len,,int,*flags); :DESCRIPTION ,,͏͚ͱΔ =,DB,API ==,grn_db_create :NAME ,,grn_db_create,,grn_db_open,I,σʔλϕʔεΛੜ੒͢Δ IUUQTHJUIVCDPNHSPPOHBHSPPOHBCMPCNBTUFSEPD"1*SE
  13. package main ! /* #cgo pkg-config: groonga #include <groonga.h> #include

    <stdlib.h> */ import "C" import "unsafe" ! func main() { C.grn_init() // TODO error handling defer C.grn_fin() // TODO error handling ! ctx := C.grn_ctx_open(0) defer C.grn_ctx_fin(ctx) // TODO error handling ! dbPath := "db" cDbPath := C.CString(dbPath) defer C.free(unsafe.Pointer(cDbPath)) db := C.grn_db_create(ctx, cDbPath, nil) if db == nil { log.Fatal("[grn_db_create] Failed to create DB") } defer C.grn_obj_close(ctx, db) ! command := "status" cCommand := C.CString(command) defer C.free(unsafe.Pointer(cCommand)) C.grn_ctx_send(ctx, cCommand, C.uint(len(command)), 0) // TODO error handling } DPNNBOEΛ$ͷจࣈྻʹ͠·͢ ίϚϯυ௕ qBHT͸ͱΓ͋͑ͣͰ
  14. 265 266 267 268 269 270 271 272 273 274

    275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 290 291 292 293 294 295 296 297 298 299 300 301 302 303 304 305 306 307 ==,grn_ctx_send :NAME ,,grn_ctx_send,I,͓͘Δ :SYNOPSIS ,((',')) ,,#include,<groonga/groonga.h> ,,unsigned,grn_ctx_send(grn_ctx,*ctx,,char,*str,,unsigned,int,str_len,,int,flags); :DESCRIPTION ,,͓͘Δ ==,grn_ctx_recv :NAME ,,grn_ctx_recv,I,͏͚ͱΔ :SYNOPSIS ,((',')) ,,#include,<groonga/groonga.h> ,,unsigned,grn_ctx_recv(grn_ctx,*ctx,,char,**str,,unsigned,int,*str_len,,int,*flags); :DESCRIPTION ,,͏͚ͱΔ =,DB,API ==,grn_db_create :NAME ,,grn_db_create,,grn_db_open,I,σʔλϕʔεΛੜ੒͢Δ IUUQTHJUIVCDPNHSPPOHBHSPPOHBCMPCNBTUFSEPD"1*SE
  15. package main ! /* #cgo pkg-config: groonga #include <groonga.h> #include

    <stdlib.h> */ import "C" import "unsafe" import "log" ! func main() { C.grn_init() // TODO error handling defer C.grn_fin() // TODO error handling ! ctx := C.grn_ctx_open(0) defer C.grn_ctx_fin(ctx) // TODO error handling ! dbPath := "db" cDbPath := C.CString(dbPath) defer C.free(unsafe.Pointer(cDbPath)) db := C.grn_db_create(ctx, cDbPath, nil) if db == nil { log.Fatal("[grn_db_create] Failed to create DB") } defer C.grn_obj_close(ctx, db) ! command := "status" cCommand := C.CString(command) defer C.free(unsafe.Pointer(cCommand)) C.grn_ctx_send(ctx, cCommand, C.uint(len(command)), 0) // TODO error handling ! var resultBuffer *C.char var resultLength C.uint var flags C.int C.grn_ctx_recv(ctx, &resultBuffer, &resultLength, &flags) // TODO error handling result := C.GoBytes(unsafe.Pointer(resultBuffer), C.int(resultLength)) ! log.Println(string(result)) }
  16. ͜Θ͘ͳ͍ w ࢝·ΓͱऴΘΓ
 HSO@JOJU HSO@pO  w ίϯςΩετ HSO@DUY ͷ࡞੒ͱഁغ


    HSO@DUY@JOJU HSO@DUY@pO  w σʔλϕʔεͷ࡞੒ɾΦʔϓϯͱΫϩʔζ
 HSO@EC@DSFBUF HSO@EC@PQFO HSO@PCK@DMPTF  w ίϚϯυͷૹ৴ͱड৴
 HSO@DUY@TFOE HSO@DUY@SFDW
  17. 39 40 41 42 43 44 45 46 47 48

    49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 ==,grn_ctx_init :NAME ,,grn_ctx_init,,grn_ctx_fin,I,grn_ctxߏ଄ମΛॳظԽ/ղ์͢Δ :SYNOPSIS ,((',')) ,,#include,<groonga/groonga.h> ,,grn_rc,grn_ctx_init(grn_ctx,*ctx,,int,flags,,grn_encoding,encoding); ,,grn_rc,grn_ctx_fin(grn_ctx,*ctx); :DESCRIPTION ,,grn_ctx͸ɺ1)Τϥʔ৘ใͷ௨஌ɺ2)API಺෦Ͱ࢖༻͢ΔϝϞϦͷ؅ཧɺ3)ΫΤϦݴޠॲཧܥͷ؅ཧͷͨΊʹ࢖༻͞ΕΔߏ଄ମͰ͋Δɻ΄ͱΜͲͷAPIؔ਺͸ୈҰҾ਺ʹgrn_ct ,,,typedef,struct,_grn_ctx,grn_ctx; ,,,struct,_grn_ctx,{ ,,,,,grn_rc,rc;,,,,,,,,,,,,,,,,,,,,,,,/*,࠷ޙʹ࣮ߦͨ͠APIͷऴྃίʔυ,*/ ,,,,,int,flags;,,,,,,,,,,,,,,,,,,,,,,,/*,಺෦ॲཧ༻,*/ ,,,,,grn_encoding,encoding;,,,,,,,,,,,/*,σϑΥϧτͷจࣈΤϯίʔσΟϯά,*/ ,,,,,unsigned,char,ntrace;,,,,,,,,,,,,/*,όοΫτϨʔεͷ਺,*/ ,,,,,unsigned,char,errlvl;,,,,,,,,,,,,/*,࠷ޙʹൃੜͨ͠ΤϥʔͷϨϕϧ,*/ ,,,,,unsigned,char,stat;,,,,,,,,,,,,,,/*,಺෦ॲཧ༻,*/ ,,,,,unsigned,int,seqno;,,,,,,,,,,,,,,/*,಺෦ॲཧ༻,*/ ,,,,,unsigned,int,subno;,,,,,,,,,,,,,,/*,಺෦ॲཧ༻,*/ ,,,,,unsigned,int,seqno2;,,,,,,,,,,,,,/*,಺෦ॲཧ༻,*/ ,,,,,unsigned,int,errline;,,,,,,,,,,,,/*,Τϥʔ͕ൃੜͨ͠Օॴͷߦ൪߸,*/ ,,,,,grn_ctx,*prev;,,,,,,,,,,,,,,,,,,,/*,಺෦ॲཧ༻,*/ ,,,,,grn_ctx,*next;,,,,,,,,,,,,,,,,,,,/*,಺෦ॲཧ༻,*/ ,,,,,const,char,*errfile;,,,,,,,,,,,,,/*,Τϥʔ͕ൃੜͨ͠ιʔεϑΝΠϧ໊,*/ ,,,,,const,char,*errfunc;,,,,,,,,,,,,,/*,Τϥʔ͕ൃੜͨؔ͠਺໊,*/ ,,,,,struct,_grn_ctx_impl,*impl;,,,,,,/*,಺෦ॲཧ༻,*/ ,,,,,void,*trace[16];,,,,,,,,,,,,,,,,,/*,όοΫτϨʔεϙΠϯλ഑ྻ,*/ ,,,,,char,errbuf[GRN_CTX_MSGSIZE];,,,,/*,࠷ޙʹൃੜͨ͠Τϥʔʹؔ͢Δϝοηʔδ,*/ ,,,}; ,,grn_ctxߏ଄ମ͸APIͰ࢖༻͢Δલʹgrn_ctx_init()ͰॳظԽ͠ͳ͚Ε͹ͳΒͳ͍ɻॳظԽ͢Δgrn_ctxߏ଄ମ΁ͷϙΠϯλΛ'ctx'ʹࢦఆ͢Δɻ'flags'ʹGRN_CTX_USE_QL IUUQTHJUIVCDPNHSPPOHBHSPPOHBCMPCNBTUFSEPD"1*SE
  18. package main ! /* #cgo pkg-config: groonga #include <groonga.h> #include

    <stdlib.h> */ import "C" import "unsafe" import "log" ! func main() { C.grn_init() // TODO error handling defer C.grn_fin() // TODO error handling ! ctx := C.grn_ctx_open(0) defer C.grn_ctx_fin(ctx) // TODO error handling ! dbPath := "db" cDbPath := C.CString(dbPath) defer C.free(unsafe.Pointer(cDbPath)) db := C.grn_db_create(ctx, cDbPath, nil) if db == nil { log.Fatal("[grn_db_create] Failed to create DB") } defer C.grn_obj_close(ctx, db) ! command := "status" cCommand := C.CString(command) defer C.free(unsafe.Pointer(cCommand)) C.grn_ctx_send(ctx, cCommand, C.uint(len(command)), 0) // TODO error handling ! var resultBuffer *C.char var resultLength C.uint var flags C.int C.grn_ctx_recv(ctx, &resultBuffer, &resultLength, &flags) // TODO error handling result := C.GoBytes(unsafe.Pointer(resultBuffer), C.int(resultLength)) ! log.Println(string(result)) } ݺͼग़ͨ͠HSO@ ͕໭Γ஋Ͱ
 ΤϥʔΛڭ͑ͯ͘ΕΔ৔߹
 ࣮͸DUYSD΋(3/@46$$&44ʹͳ͍ͬͯΔ
  19. package main ! /* #cgo pkg-config: groonga #include <groonga.h> #include

    <stdlib.h> */ import "C" import "unsafe" import "log" ! func main() { C.grn_init() // TODO error handling defer C.grn_fin() // TODO error handling ! ctx := C.grn_ctx_open(0) defer C.grn_ctx_fin(ctx) // TODO error handling ! dbPath := "db" cDbPath := C.CString(dbPath) defer C.free(unsafe.Pointer(cDbPath)) db := C.grn_db_create(ctx, cDbPath, nil) if db == nil { log.Fatal("[grn_db_create] Failed to create DB") } defer C.grn_obj_close(ctx, db) ! command := "status" cCommand := C.CString(command) defer C.free(unsafe.Pointer(cCommand)) C.grn_ctx_send(ctx, cCommand, C.uint(len(command)), 0) // TODO error handling ! var resultBuffer *C.char var resultLength C.uint var flags C.int C.grn_ctx_recv(ctx, &resultBuffer, &resultLength, &flags) // TODO error handling result := C.GoBytes(unsafe.Pointer(resultBuffer), C.int(resultLength)) ! log.Println(string(result)) } HUY@DUY@TFOEʹண໨
  20. ݺͼग़ͨ͠HSO@ ͕໭Γ஋Ͱ
 ΤϥʔΛڭ͑ͯ͘ΕΔ৔߹ /* ུ */ ! command := "statussssss"

    cCommand := C.CString(command) defer C.free(unsafe.Pointer(cCommand)) rc := C.grn_ctx_send(ctx, cCommand, C.uint(len(command)), 0) if rc != C.GRN_SUCCESS { log.Fatal("[grn_ctx_send(rc)]") } if ctx.rc != C.GRN_SUCCESS { message := C.GoString(&ctx.errbuf[0]) log.Fatal("[grn_ctx_send(ctx.rc)] ", message) } ! /* ུ */ ݺͼग़͠͸੒ޭͨ͠΋ͷͷɺ
 ࣮ߦʹ͸ࣦഊͯ͠ίϯςΩετʹΤϥʔ͕ೖΔ৔߹ UZQPͨ͠