extism / cpp-sdk

Extism C++ Host SDK
BSD 3-Clause "New" or "Revised" License
7 stars 3 forks source link

docs: strings #20

Open konsumer opened 4 weeks ago

konsumer commented 4 weeks ago

I am playing with cpp host, and I noticed the README is off, and also the unit-tests do not have an example of what I am trying to do.

Imagine a single trace function, wasm-side:

EXTISM_IMPORT("extism:host/user", "trace")
extern void _null0_trace_real(ExtismHandle);

// Log a string (using printf-style)
void trace(const char* format, ...) {
  char null0_traceBuffer[NULL0_TRACE_SIZE];
  va_list args;
  va_start(args, format);
  vsnprintf(null0_traceBuffer, NULL0_TRACE_SIZE, format, args);
  va_end(args);

  ExtismHandle handle = extism_alloc(NULL0_TRACE_SIZE);
  extism_store_to_handle(handle, 0, null0_traceBuffer, NULL0_TRACE_SIZE);
  _null0_trace_real(handle);
}

This will perform the string-formatting, wasm-side, and just send a simple string to host to be logged.

After a bit of fighting, and asking in disocrd (thanks @bhelx !) I worked out in the host, you can expose it like this:

auto trace_in = std::vector<extism::ValType>{extism::ValType::ExtismValType_I64};
auto null0_host_trace = extism::Function(
    "trace",
    trace_in,
    {},
    [](extism::CurrentPlugin plugin, void* user_data) {
      cout << plugin.inputStringView(0) << endl;
    },
    NULL,
    NULL);

Plugin plugin(bytes, true, {null0_host_trace});

But the README makes no mention of inputStringView and there were no unit-tests about this. The closest I saw was the keyval example, which uses a few functions that are undefined.

G4Vi commented 3 weeks ago

Thanks for the report, looks like the docs were never cleaned up after I added the std::string_view optimizations, testing it is a good idea too. Contributions welcome, otherwise I'll eventually get around to fixing this.

Since it was mentioned in discord, just to clarify, a std::string_view is just a slice or pointer and length combo. The idea is that std::string_view can be very cheaply constructed from existing data and is lightweight to pass around and copy (as it doesn't include the actual data). It was a much needed improvement to the C++ standard library as it reduces cases where using raw pointers is tempting or the need to promote everything to std::string to for passing std::string& .