Skip to content

Instantly share code, notes, and snippets.

@tghpereira
Last active October 21, 2023 16:58
Show Gist options
  • Save tghpereira/d5802a0a9d55672545618904ca6b45fb to your computer and use it in GitHub Desktop.
Save tghpereira/d5802a0a9d55672545618904ca6b45fb to your computer and use it in GitHub Desktop.
Example Bun FFI C++
import { dlopen } from 'bun:ffi';
// build C++ in Linux -> g++ -shared -o test.so ./test.cpp -std=c++23 -lstdc++ -fPIC
export const addons = dlopen('test.so', {
create: {
args: ['callback'],
returns: 'pointer',
},
summon: {
args: ['pointer', 'pointer'],
returns: 'void',
},
destroy: {
args: ['pointer'],
returns: 'void',
},
});
struct Memo {
void(*javascript)(char *);
};
class Example {
private:
Memo * memo;
public:
explicit Example(void(*javascript)(char *));
~Example();
void execute(char* args);
};
Example::Example(void(*javascript)(char *)){
this -> memo = new Memo{javascript};
}
Example::~Example(){
delete this -> memo;
}
void Example::execute(char* args){
this -> memo -> javascript(args);
}
extern "C" {
Example * create(void(*javascript)(char*)){
auto * example = new Example(javascript);
return example;
}
void summon(Example * example, char* args){
example -> execute(args);
}
void destroy(Example * example){
delete example;
}
}
import { addons } from './addons';
import { describe, it, expect, afterAll } from 'bun:test';
import { CString, JSCallback } from 'bun:ffi';
const summon = new JSCallback(ptr => expect(new CString(ptr).toString()).toEqual('Lorem is simple'), {
args: ['pointer'],
returns: 'void',
});
const example = addons.symbols.create(summon.ptr);
describe('Integration C++ test', () => {
afterAll(() => {
addons.symbols.destroy(example);
summon.close();
addons.close();
});
it('should be possible create a Example', () => {
expect(example).not.toEqual(null);
});
it('should be possivel call a summon of Example', () => {
expect(addons.symbols.summon(example, new TextEncoder().encode('Lorem is simple\0'))).not.fail();
});
});
import { JSCallback } from 'bun:ffi';
import { addons } from './addons';
const summon = new JSCallback(ptr => console.log(new CString(ptr)), {
args: ['pointer'],
returns: 'void',
});
const example = addons.symbols.create(summon.ptr);
addons.symbols.summon(example, new TextEncoder().encode('Lorem is simple\0'));
addons.symbols.destroy(example);
summon.close();
addons.close();
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment