Skip to content

Commit 8544261

Browse files
authored
Initialize DLL on nif load (#126)
1 parent 66b5427 commit 8544261

File tree

2 files changed

+32
-54
lines changed

2 files changed

+32
-54
lines changed

c_src/dll_loader/adbc_dll_loader.cpp

Lines changed: 30 additions & 48 deletions
Original file line numberDiff line numberDiff line change
@@ -9,39 +9,38 @@
99
#include <winbase.h>
1010
#include <wchar.h>
1111

12-
#define NIF(NAME) ERL_NIF_TERM NAME(ErlNifEnv *env, int argc, const ERL_NIF_TERM argv[])
13-
14-
// Helper for returning `{:error, msg}` from NIF.
15-
ERL_NIF_TERM error(ErlNifEnv *env, const char *msg)
16-
{
17-
ERL_NIF_TERM atom = enif_make_atom(env, "error");
18-
ERL_NIF_TERM msg_term = enif_make_string(env, msg, ERL_NIF_LATIN1);
19-
return enif_make_tuple2(env, atom, msg_term);
12+
ERL_NIF_TERM adbc_dll_unused(ErlNifEnv *env, int argc, const ERL_NIF_TERM argv[]) {
13+
(void)(env);
14+
(void)(argc);
15+
(void)(argv);
16+
return enif_make_int(env, 0);
2017
}
2118

22-
// Helper for returning `{:ok, term}` from NIF.
23-
ERL_NIF_TERM ok(ErlNifEnv *env)
24-
{
25-
return enif_make_atom(env, "ok");
26-
}
19+
int upgrade(ErlNifEnv *env, void **priv_data, void **old_priv_data, ERL_NIF_TERM load_info) {
20+
// Silence "unused var" warnings.
21+
(void)(env);
22+
(void)(priv_data);
23+
(void)(old_priv_data);
24+
(void)(load_info);
2725

28-
NIF(add_dll_directory) {
29-
static bool path_updated = false;
30-
if (path_updated) return ok(env);
26+
return 0;
27+
}
3128

29+
int load(ErlNifEnv *,void **,ERL_NIF_TERM) {
3230
wchar_t dll_path_c[65536];
3331
char err_msg[128] = { '\0' };
3432
HMODULE hm = NULL;
35-
if (GetModuleHandleExW(GET_MODULE_HANDLE_EX_FLAG_FROM_ADDRESS | GET_MODULE_HANDLE_EX_FLAG_UNCHANGED_REFCOUNT, (LPCWSTR)&add_dll_directory, &hm) == 0) {
36-
int ret = GetLastError();
37-
snprintf(err_msg, sizeof(err_msg) - 1, "GetModuleHandle failed, error = %d\r\n", ret);
38-
return error(env, err_msg);
33+
34+
if (GetModuleHandleExW(GET_MODULE_HANDLE_EX_FLAG_FROM_ADDRESS | GET_MODULE_HANDLE_EX_FLAG_UNCHANGED_REFCOUNT, (LPCWSTR)&load, &hm) == 0) {
35+
int ret = GetLastError();
36+
printf("GetModuleHandle failed, error = %d\n", ret);
37+
return 1;
3938
}
4039

4140
if (GetModuleFileNameW(hm, (LPWSTR)dll_path_c, sizeof(dll_path_c)) == 0) {
42-
int ret = GetLastError();
43-
snprintf(err_msg, sizeof(err_msg) - 1, "GetModuleFileName failed, error = %d\r\n", ret);
44-
return error(env, err_msg);
41+
int ret = GetLastError();
42+
printf("GetModuleFileName failed, error = %d\n", ret);
43+
return 1;
4544
}
4645

4746
std::wstring dll_path = dll_path_c;
@@ -64,44 +63,27 @@ NIF(add_dll_directory) {
6463

6564
SetDefaultDllDirectories(LOAD_LIBRARY_SEARCH_DEFAULT_DIRS | LOAD_LIBRARY_SEARCH_USER_DIRS);
6665
DLL_DIRECTORY_COOKIE ret = AddDllDirectory(directory_pcwstr);
66+
6767
if (ret == 0) {
6868
DWORD last_error = GetLastError();
6969
LPTSTR error_text = nullptr;
7070
FormatMessage(FORMAT_MESSAGE_FROM_SYSTEM | FORMAT_MESSAGE_ALLOCATE_BUFFER | FORMAT_MESSAGE_IGNORE_INSERTS, NULL, HRESULT_FROM_WIN32(last_error), MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT), (LPTSTR)&error_text, 0, NULL);
71+
7172
if (error_text != nullptr) {
72-
ERL_NIF_TERM ret_term = error(env, error_text);
73-
LocalFree(error_text);
74-
return ret_term;
73+
printf("Error: %s\n", error_text);
74+
LocalFree(error_text);
7575
} else {
76-
ERL_NIF_TERM ret_term = error(env, "error happened when adding adbc driver runtime path, but cannot get formatted error message");
77-
return ret_term;
76+
printf("Error: error happened when adding adbc driver runtime path, but cannot get formatted error message\n");
7877
}
79-
}
80-
path_updated = true;
81-
return ok(env);
82-
}
83-
84-
int upgrade(ErlNifEnv *env, void **priv_data, void **old_priv_data, ERL_NIF_TERM load_info) {
85-
// Silence "unused var" warnings.
86-
(void)(env);
87-
(void)(priv_data);
88-
(void)(old_priv_data);
89-
(void)(load_info);
9078

91-
return 0;
92-
}
79+
return 1;
80+
}
9381

94-
int load(ErlNifEnv *,void **,ERL_NIF_TERM) {
9582
return 0;
9683
}
9784

98-
#define F(NAME, ARITY) \
99-
{ \
100-
#NAME, ARITY, NAME, 0 \
101-
}
102-
10385
static ErlNifFunc nif_functions[] = {
104-
F(add_dll_directory, 0)
86+
{"__unused__", 0, adbc_dll_unused, 0}
10587
};
10688

10789
ERL_NIF_INIT(Elixir.Adbc.DLLLoaderNif, nif_functions, load, NULL, upgrade, NULL);

lib/adbc_dll_loader_nif.ex

Lines changed: 2 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -11,17 +11,13 @@ defmodule Adbc.DLLLoaderNif do
1111
File.mkdir_p!(Path.join(priv_dir, "bin"))
1212
path = :filename.join(priv_dir, ~c"adbc_dll_loader")
1313
:erlang.load_nif(path, 0)
14-
add_dll_directory()
1514

1615
_ ->
1716
:ok
1817
end
1918
end
2019

21-
def add_dll_directory do
22-
case :os.type() do
23-
{:win32, _} -> :erlang.nif_error(:not_loaded)
24-
_ -> :ok
25-
end
20+
def __unused__ do
21+
0
2622
end
2723
end

0 commit comments

Comments
 (0)