1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108
|
/* Copyright (c) 1993-2008 by Richard Kelsey and Jonathan Rees.
See file COPYING. */
/*
* Load DLLs on Windows.
*/
#include <windows.h>
#include "scheme48.h"
#include "io.h"
extern int s48_utf_8of16_to_utf_16(const unsigned char* utf_8of16,
LPWSTR utf_16,
int* errorp);
static s48_value
shared_object_dlopen(s48_value name, s48_value complete_name_p)
{
S48_DECLARE_GC_PROTECT(1);
HINSTANCE handle;
s48_value res;
s48_value full_name;
WCHAR* name_utf16;
size_t len = strlen(s48_extract_byte_vector(name));
S48_GC_PROTECT_1(name);
if (!S48_EQ(S48_FALSE, complete_name_p))
{
full_name = s48_make_byte_vector(len + 5);
memcpy(s48_extract_byte_vector(full_name),
s48_extract_byte_vector(name),
len);
memcpy(s48_extract_byte_vector(full_name) + len,
".dll",
5);
len += 4;
}
else
full_name = name;
name_utf16 = malloc(sizeof(WCHAR) * (len + 1));
if (name_utf16 == NULL)
s48_raise_out_of_memory_error();
s48_utf_8of16_to_utf_16(s48_extract_byte_vector(full_name), name_utf16, NULL);
handle = LoadLibraryW(name_utf16);
free(name_utf16);
if (handle == NULL)
s48_raise_string_os_error(ps_error_string(GetLastError()));
res = S48_MAKE_VALUE(HINSTANCE);
S48_SET_VALUE(res, HINSTANCE, handle);
S48_GC_UNPROTECT();
return res;
}
static s48_value
shared_object_dlsym(s48_value handle, s48_value name)
{
void *entry;
HINSTANCE native_handle;
char *native_name;
native_handle = S48_EXTRACT_VALUE(handle, HINSTANCE);
native_name = s48_extract_byte_vector(name);
entry = GetProcAddress(native_handle, native_name);
if (entry == NULL)
s48_raise_string_os_error(ps_error_string(GetLastError()));
return s48_enter_pointer(entry);
}
static s48_value
shared_object_dlclose(s48_value handle)
{
HINSTANCE native_handle = S48_EXTRACT_VALUE(handle, HINSTANCE);
if (!FreeLibrary(native_handle) < 0)
s48_raise_string_os_error(ps_error_string(GetLastError()));
return S48_UNSPECIFIC;
}
typedef void (*thunk)();
static s48_value
shared_object_call_thunk(s48_value value)
{
thunk entry;
entry = S48_EXTRACT_VALUE(value, thunk);
entry();
return S48_UNSPECIFIC;
}
void
s48_init_dynlink(void)
{
S48_EXPORT_FUNCTION(shared_object_dlopen);
S48_EXPORT_FUNCTION(shared_object_dlsym);
S48_EXPORT_FUNCTION(shared_object_dlclose);
S48_EXPORT_FUNCTION(shared_object_call_thunk);
}
|