mirror of
https://github.com/logos-messaging/nim-ffi.git
synced 2026-06-22 01:10:03 +00:00
docs(examples): Go example reads typed struct returns
Echo/Complex/Schedule now return typed Go structs (EchoResponse, ComplexResponse, ScheduleResult); print their fields instead of an "ok" line. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
This commit is contained in:
parent
0a8b53a06d
commit
0bba42d2a2
@ -29,8 +29,9 @@ overwritten each time and `gofmt`-finalized.
|
||||
|
||||
Each call deep-copies its arguments across the FFI thread, so the Go-side C
|
||||
allocations are freed (via `defer`) as soon as the call returns. String-returning
|
||||
methods give back a Go `string`; struct-returning methods deliver their CBOR
|
||||
encoding (decode it with a Go CBOR library if needed).
|
||||
methods give back a Go `string`; **struct-returning methods give back a typed Go
|
||||
struct** — the C-POD return is read into Go inside the result callback (delivered
|
||||
via a `runtime/cgo.Handle`), so the caller never touches C memory.
|
||||
|
||||
## Build & run
|
||||
|
||||
@ -44,14 +45,15 @@ Expected output:
|
||||
```
|
||||
created timer
|
||||
version: nim-timer v0.1.0
|
||||
echo: ok (struct param round-tripped)
|
||||
complex: ok (seq/option graph deep-copied)
|
||||
schedule: ok (three struct params in one call)
|
||||
echo: echoed="hello from Go" timerName="go-native-demo"
|
||||
complex: itemCount=2 hasNote=true summary="received 2 messages, note=a note, retries=3"
|
||||
schedule: jobId="go-native-demo:nightly" willRunCount=12
|
||||
done
|
||||
```
|
||||
|
||||
`Echo`, `Complex` and `Schedule` take `{.ffi.}` structs, slices and optionals
|
||||
directly — previously these procs were skipped by the Go generator.
|
||||
directly and return typed Go structs — previously these procs were skipped by
|
||||
the Go generator.
|
||||
|
||||
For the cross-process / cross-machine path (CBOR over a socket), see
|
||||
[`../ipc`](../ipc); a Go client could speak the same wire protocol using any Go
|
||||
|
||||
@ -3,8 +3,8 @@
|
||||
// The generated cgo package marshals each {.ffi.} struct param into its flat
|
||||
// C-POD form and passes it to the native ABI by value — so methods that take
|
||||
// structs, sequences and optionals (Echo, Complex, Schedule) are now callable
|
||||
// directly with idiomatic Go types. String-returning calls (Version) come back
|
||||
// as a Go string; struct-returning calls deliver their CBOR encoding.
|
||||
// directly with idiomatic Go types. Struct-returning calls hand back a typed Go
|
||||
// struct too (read out of the C-POD inside the result callback).
|
||||
package main
|
||||
|
||||
import (
|
||||
@ -31,15 +31,16 @@ func main() {
|
||||
fmt.Printf("version: %s\n", v)
|
||||
}
|
||||
|
||||
// Struct param: EchoRequest { Message string; DelayMs int64 }.
|
||||
if _, err := node.Echo(timer.EchoRequest{Message: "hello from Go", DelayMs: 5}); err != nil {
|
||||
// Struct param + typed struct return: EchoResponse { Echoed; TimerName }.
|
||||
if resp, err := node.Echo(timer.EchoRequest{Message: "hello from Go", DelayMs: 5}); err != nil {
|
||||
log.Printf("echo: %v", err)
|
||||
} else {
|
||||
fmt.Println("echo: ok (struct param round-tripped)")
|
||||
fmt.Printf("echo: echoed=%q timerName=%q\n", resp.Echoed, resp.TimerName)
|
||||
}
|
||||
|
||||
// Deeply nested: slice of structs, slice of strings, two optionals.
|
||||
_, err = node.Complex(timer.ComplexRequest{
|
||||
// Deeply nested param + typed return: slice of structs, slice of strings,
|
||||
// two optionals in; ComplexResponse { Summary; ItemCount; HasNote } out.
|
||||
cresp, err := node.Complex(timer.ComplexRequest{
|
||||
Messages: []timer.EchoRequest{
|
||||
{Message: "one", DelayMs: 0},
|
||||
{Message: "two", DelayMs: 0},
|
||||
@ -51,11 +52,12 @@ func main() {
|
||||
if err != nil {
|
||||
log.Printf("complex: %v", err)
|
||||
} else {
|
||||
fmt.Println("complex: ok (seq/option graph deep-copied)")
|
||||
fmt.Printf("complex: itemCount=%d hasNote=%v summary=%q\n",
|
||||
cresp.ItemCount, cresp.HasNote, cresp.Summary)
|
||||
}
|
||||
|
||||
// Multiple struct params at once.
|
||||
_, err = node.Schedule(
|
||||
// Multiple struct params at once; ScheduleResult out.
|
||||
sresp, err := node.Schedule(
|
||||
timer.JobSpec{Name: "nightly", Payload: []string{"x"}, Priority: 5},
|
||||
timer.RetryPolicy{MaxAttempts: 3, BackoffMs: 100, RetryOn: []string{"timeout"}},
|
||||
timer.ScheduleConfig{StartAtMs: 1000, IntervalMs: 5000, Jitter: intp(50)},
|
||||
@ -63,7 +65,7 @@ func main() {
|
||||
if err != nil {
|
||||
log.Printf("schedule: %v", err)
|
||||
} else {
|
||||
fmt.Println("schedule: ok (three struct params in one call)")
|
||||
fmt.Printf("schedule: jobId=%q willRunCount=%d\n", sresp.JobId, sresp.WillRunCount)
|
||||
}
|
||||
|
||||
fmt.Println("done")
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user