Skip to content

Instantly share code, notes, and snippets.

@kugel-
Created October 22, 2016 16:24
Show Gist options
  • Save kugel-/7918c1e87f38c0a09d303b93a71927dd to your computer and use it in GitHub Desktop.
Save kugel-/7918c1e87f38c0a09d303b93a71927dd to your computer and use it in GitHub Desktop.
/*
cc $(pkg-config --cflags --libs-only-L ruby-2.3) -Wl,-export-dynamic test.c -o test $(pkg-config --libs ruby-2.3)
*/
#include <stdio.h>
#include <dlfcn.h>
#include <pthread.h>
#include <ruby.h>
#include <ruby/thread.h>
const char script[] =
"require 'rubygems'\n"
"require 'ffi'\n"
"module LibWrap\n"
" extend FFI::Library\n"
" ffi_lib [FFI::CURRENT_PROCESS, '']\n"
" callback :completion_function, [:string, :long, :uint8], :void\n"
" attach_function :do_work, [:pointer, :completion_function], :int\n"
" Callback = Proc.new do |buf_ptr, count, code|\n"
" puts(\"ruby says #{buf_ptr}\")\n"
" end\n"
"end\n"
"\n"
"LibWrap.do_work(\"test\", LibWrap::Callback)\n";
typedef void completion_function(char *buffer, long count, unsigned char code);
extern int do_work(char *buffer, completion_function *);
static completion_function *ruby_func;
int do_work(char *buffer, completion_function *fn)
{
/* Calling fn directly here works */
ruby_func = fn;
return 0;
}
static void*
thread_call_func(void *arg)
{
completion_function *fn = arg;
fn("thread", 5, 0);
return NULL;
}
static void *
join_pthread(void *arg)
{
pthread_t tid = *(pthread_t *) arg;
pthread_join(tid, NULL);
}
static void
nop(void *data)
{
}
int main()
{
int state = 0;
VALUE ret;
/* construct the VM */
ruby_init();
ruby_init_loadpath();
rb_eval_string_protect(script, &state);
if (state)
{
VALUE e = rb_errinfo();
ret = rb_funcall(e, rb_intern("message"), 0);
fprintf(stderr, "exc %s\n", StringValueCStr(ret));
rb_set_errinfo(Qnil);
}
else
{
pthread_t th;
pthread_create(&th, NULL, thread_call_func, ruby_func);
rb_thread_call_without_gvl(join_pthread, &th, nop, NULL);
}
/* destruct the VM */
return ruby_cleanup(0);
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment