Movatterモバイル変換


[0]ホーム

URL:


Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Sign up
Appearance settings

Extism C++ Host SDK - easily run WebAssembly modules / plugins from C++ applications

License

NotificationsYou must be signed in to change notification settings

extism/cpp-sdk

Repository files navigation

The C++ SDK for integrating with theExtism runtime. Add this library in your host C++ applications to run Extism plugins.

Join theExtism Discord and chat with us!

Building and Installation

Install Dependencies

  • libextism
  • cmake and jsoncpp
    • Debian:sudo apt install cmake jsoncpp
    • macOS:brew install cmake jsoncpp

If you wish to do link jsoncpp statically, or do an in-tree build, SeeAlternative Dependency Strategies.

Build and Install cpp-sdk

cmake -B buildcmake --build build -jsudo cmake --install build

Getting Started

To add the cpp-sdk to a CMake project:

find_package(extism-cpp)target_link_libraries(getting-started extism-cpp)

Loading a Plug-in

The primary concept in Extism is theplug-in. A plug-in is a code module stored in a.wasm file.

Plug-in code can come from a file on disk, object storage or any number of places. Since you may not have one handy, let's load a demo plug-in from the web. Let'sstart by creating a main function that loads a plug-in:

#include<extism.hpp>intmain(void) {constauto manifest =extism::Manifest::wasmURL("https://github.com/extism/plugins/releases/""latest/download/count_vowels.wasm");  extism::Pluginplugin(manifest,true);}

Calling A Plug-in's Exports

This plug-in was written in Rust and it does one thing, it counts vowels in a string. It exposes one "export" function:count_vowels. We can call exports usingPlugin::call.Let's add code to callcount_vowels to our main func:

#include<extism.hpp>#include<iostream>#include<string>intmain(void) {// ...const std::stringhello("Hello, World!");auto out = plugin.call("count_vowels", hello);  std::stringresponse(out.string());  std::cout << response << std::endl;// => {"count":3,"total":3,"vowels":"aeiouAEIOU"}}

Build it:

cmake -B build&& cmake --build build

Running this should print out the JSON vowel count report:

./build/getting-started{"count":3,"total":3,"vowels":"aeiouAEIOU"}

All exports have the same interface, optional bytes in and optional bytes out. This plug-in happens to take a string and return a JSON encoded string with a report of results.

Plug-in State

Plug-ins may be stateful or stateless. Plug-ins can maintain state between calls using variables. Our count vowels plug-in remembers the total number of counted vowels in the "total" key in the result. You can see this by making subsequent calls to the export:

const std::stringhello("Hello, World!");auto out = plugin.call("count_vowels", hello);  std::stringresponse(out.string());  std::cout << response << std::endl;// => {"count":3,"total":3,"vowels":"aeiouAEIOU"}  out = plugin.call("count_vowels", hello);  response = out.string();  std::cout << response << std::endl;// => {"count":3,"total":6,"vowels":"aeiouAEIOU"}

The state variables will persist until the plug-in is freed or reinitialized.

Configuration

Plug-ins may optionally take a configuration object. This is a static way to configure the plug-in. Our count-vowels plugin takes an optional configuration to change out which characters are considered vowels. Example:

#include<extism.hpp>intmain(void) {auto manifest =extism::Manifest::wasmURL("https://github.com/extism/plugins/releases/""latest/download/count_vowels.wasm");  manifest.setConfig("vowels","aeiouyAEIOUY");  extism::Pluginplugin(manifest,true);const std::stringhello("Yellow, World!");auto out = plugin.call("count_vowels", hello);  std::stringresponse(out.string());  std::cout << response << std::endl;// => {"count":4,"total":4,"vowels":"aeiouyAEIOUY"}}

Host Functions

Let's extend our count-vowels example a little bit: Instead of storing thetotal in an ephemeral plug-in var, let's store it in a persistent key-value store!

Wasm can't use our KV store on it's own. This is whereHost Functions come in.

Host functions allow us to grant new capabilities to our plug-ins from our application. In this case, they are native C++ functions that are passed to and can can be invoked by the plug-in.

Let's load the manifest like usual but load up thecount_vowels_kvstore plug-in:

constauto manifest =extism::Manifest::wasmURL("https://github.com/extism/plugins/releases/""latest/download/count_vowels_kvstore.wasm");

Note: The source code for this ishere and is written in rust, but it could be written in any of our PDK languages.

Unlike our previous plug-in, this plug-in expects you to provide host functions that satisfy its import interface for a KV store.

We want to expose two functions to our plugin,kv_write which writes a bytes value to a key andkv_read which reads the bytes at the given key:

// pretend this is Redis or something :)  std::map<std::string, std::vector<uint8_t>> kvStore;auto t = std::vector<extism::ValType>{extism::ValType::I64};auto kvRead = extism::Function("kv_read", t, t,      [&kvStore](extism::CurrentPlugin plugin,void *user_data) {constauto it = kvStore.find(plugin.inputString());if (it == kvStore.end()) {const std::vector<uint8_t> zeros{0,0,0,0};          plugin.output(zeros.data(), zeros.size());return;        }        plugin.output(it->second.data(), it->second.size());      });auto kvWrite = extism::Function("kv_write", {extism::ValType::I64, extism::ValType::I64}, {},      [&kvStore](extism::CurrentPlugin plugin,void *user_data) {constauto key = plugin.inputString(0);auto value = plugin.inputBuffer(1);        kvStore[key] = value.vector();      });

We need to pass these imports to the plug-in to create them. All imports of a plug-in must be satisfied for it to be initialized:

  extism::Pluginplugin(manifest,true, {kvRead, kvWrite});

Now, we can demo it:

const std::stringhello("Hello, World!");auto out = plugin.call("count_vowels", hello);  std::stringresponse(out.string());  std::cout << response << std::endl;// => {"count":3,"total":3,"vowels":"aeiouAEIOU"}  out = plugin.call("count_vowels", hello);  response = out.string();  std::cout << response << std::endl;// => {"count":3,"total":6,"vowels":"aeiouAEIOU"}

Linking

CMake

find_package(extism-cpp)target_link_libraries(target_name extism-cpp)

or statically:

find_package(extism-cpp)target_link_libraries(target_name extism-cpp-static)

pkg-config

pkg-config --libs extism-cpp

or statically:

pkg-config --static --libs extism-cpp-static

Alternative Dependency Strategies

link jsoncpp statically

For builds usingextism-cpp-static to be static other than glibc, etc. jsoncppmust be linked statically. jsoncpp provided by package managers often isn'tprovided as a static library.

Building and installing jsoncpp from source (includingjsoncpp_static):

git clone https://github.com/open-source-parsers/jsoncppcd jsoncppcmake -B build&& cmake --build build -jmake -C build install

In-Tree builds

If you wish, instead of using installed deps, you can do an in-tree build!

For example:

mkdir extism-cpp-projectcd extism-cpp-projectgit initgit submodule add https://github.com/extism/extism.gitgit submodule add https://github.com/open-source-parsers/jsoncpp.gitgit submodule add https://github.com/extism/cpp-sdk.gitcd cpp-sdkcmake -DEXTISM_CPP_BUILD_IN_TREE=1 -B build&& cmake --build build

Fallback Dependencies

IfEXTISM_CPP_BUILD_IN_TREE is not set andfind_package fails, the dependency is fetched from the internet usingFetchContent and built from source.

The author believes this is the worst way to deal with the deps as it requires building them from source and doesn't use a centrally managed, flat tree of dependencies. It's provided just as a cross-platform convenience.

Testing

cmake --build build --targettest

About

Extism C++ Host SDK - easily run WebAssembly modules / plugins from C++ applications

Resources

License

Stars

Watchers

Forks

Packages

No packages published

[8]ページ先頭

©2009-2025 Movatter.jp