diff options
Diffstat (limited to 'ext/ffi_c/DynamicLibrary.c')
-rw-r--r-- | ext/ffi_c/DynamicLibrary.c | 29 |
1 files changed, 25 insertions, 4 deletions
diff --git a/ext/ffi_c/DynamicLibrary.c b/ext/ffi_c/DynamicLibrary.c index 2e0bf4b..bcbc8de 100644 --- a/ext/ffi_c/DynamicLibrary.c +++ b/ext/ffi_c/DynamicLibrary.c @@ -61,6 +61,7 @@ static size_t library_memsize(const void *); static VALUE symbol_allocate(VALUE klass); static VALUE symbol_new(VALUE library, void* address, VALUE name); static void symbol_mark(void *data); +static void symbol_compact(void *data); static size_t symbol_memsize(const void *data); static const rb_data_type_t rbffi_library_data_type = { @@ -81,6 +82,7 @@ static const rb_data_type_t library_symbol_data_type = { .dmark = symbol_mark, .dfree = RUBY_TYPED_DEFAULT_FREE, .dsize = symbol_memsize, + ffi_compact_callback( symbol_compact ) }, .parent = &rbffi_pointer_data_type, // IMPORTANT: WB_PROTECTED objects must only use the RB_OBJ_WRITE() @@ -223,8 +225,19 @@ dl_open(const char* name, int flags) static void dl_error(char* buf, int size) { - FormatMessageA(FORMAT_MESSAGE_FROM_SYSTEM, NULL, GetLastError(), - 0, buf, size, NULL); + // Get the last error code + DWORD error = GetLastError(); + + // Get the associated message + LPSTR message = NULL; + FormatMessageA(FORMAT_MESSAGE_FROM_SYSTEM | FORMAT_MESSAGE_ALLOCATE_BUFFER, + NULL, error, 0, (LPSTR)&message, 0, NULL); + + // Update the passed in buffer + snprintf(buf, size, "Failed with error %d: %s", error, message); + + // Free the allocated message + LocalFree(message); } #endif @@ -273,8 +286,16 @@ static void symbol_mark(void *data) { LibrarySymbol *sym = (LibrarySymbol *)data; - rb_gc_mark(sym->base.rbParent); - rb_gc_mark(sym->name); + rb_gc_mark_movable(sym->base.rbParent); + rb_gc_mark_movable(sym->name); +} + +static void +symbol_compact(void *data) +{ + LibrarySymbol *sym = (LibrarySymbol *)data; + ffi_gc_location(sym->base.rbParent); + ffi_gc_location(sym->name); } static size_t |