Skip to content

Commit

Permalink
add DLL search path resolution for chugin dependencies (windows) (#474)
Browse files Browse the repository at this point in the history
* add AddDllDirectory() functionality for chugin deps (windows)

* add option to activate add-dll-dir search paths

* use platformPath in import_chugin_opt()
  • Loading branch information
gewang authored Nov 2, 2024
1 parent 21bcf34 commit 0696cd8
Show file tree
Hide file tree
Showing 3 changed files with 43 additions and 7 deletions.
35 changes: 33 additions & 2 deletions src/core/chuck_compile.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1524,6 +1524,8 @@ t_CKBOOL Chuck_Compiler::import_chugin_opt( const string & path, const string &
{
// get env
Chuck_Env * env = this->env();
// platform-specific path (below: will use the appropriate '/' vs '\\')
string platformPath = path;

// NOTE this (verbose >= 5) is more informative if the chugin crashes, we can see the name
EM_log( CK_LOG_INFO, "@import loading [chugin] %s...", name.c_str() );
Expand All @@ -1535,8 +1537,24 @@ t_CKBOOL Chuck_Compiler::import_chugin_opt( const string & path, const string &
// clear error string
errorStr = "";

#if defined(__PLATFORM_WINDOWS__)
// replace '/' with '\\'
std::replace( platformPath.begin(), platformPath.end(), '/', '\\' );
// the dll search path to add
string dll_path = extract_filepath_dir( platformPath );
// the relateive _deps directory
string dll_deps_path = dll_path + "_deps\\";
// convert to wchar
wstring dll_pathw = wstring( dll_path.begin(), dll_path.end() );
wstring dll_deps_pathw = wstring( dll_deps_path.begin(), dll_deps_path.end() );
// add to the dll search path, for resolving the chugin's own DLL dependencies
DLL_DIRECTORY_COOKIE cookie_path = AddDllDirectory( dll_pathw.c_str() );
// add the relateive _deps directory to the search path as well
DLL_DIRECTORY_COOKIE cookie_deps_path = AddDllDirectory( dll_deps_pathw.c_str() );
#endif

// load (but don't query yet; lazy mode == TRUE)
if( dll->load( path.c_str(), CK_QUERY_FUNC, TRUE) )
if( dll->load( platformPath.c_str(), CK_QUERY_FUNC, TRUE) )
{
// probe it
dll->probe();
Expand Down Expand Up @@ -1575,6 +1593,8 @@ t_CKBOOL Chuck_Compiler::import_chugin_opt( const string & path, const string &
}
EM_log( CK_LOG_HERALD, "%s '%s'...", TC::blue("skipping",true).c_str(), path.c_str() );
EM_poplog();
// set error string
errorStr = dll->last_error();
// go to error for cleanup
goto error;
}
Expand All @@ -1589,6 +1609,8 @@ t_CKBOOL Chuck_Compiler::import_chugin_opt( const string & path, const string &
EM_pushlog();
EM_log( CK_LOG_HERALD, "reason: %s", TC::orange(dll->last_error(),true).c_str() );
EM_poplog();
// set error string
errorStr = dll->last_error();
// go to error for cleanup
goto error;
}
Expand All @@ -1601,6 +1623,11 @@ t_CKBOOL Chuck_Compiler::import_chugin_opt( const string & path, const string &
m_importRegistry.commit( dll );
// commit operator overloads | 1.5.1.5
env->op_registry.preserve();
#if defined(__PLATFORM_WINDOWS__)
// undo the AddDllDirectory()
if( cookie_path ) RemoveDllDirectory( cookie_path );
if( cookie_deps_path ) RemoveDllDirectory( cookie_deps_path );
#endif
// return home successful
return TRUE;

Expand All @@ -1609,7 +1636,11 @@ t_CKBOOL Chuck_Compiler::import_chugin_opt( const string & path, const string &
CK_SAFE_DELETE( dll );
// rollback operator overloads | 1.5.1.5
env->op_registry.reset2local();

#if defined(__PLATFORM_WINDOWS__)
// undo the AddDllDirectory()
if( cookie_path ) RemoveDllDirectory( cookie_path );
if( cookie_deps_path ) RemoveDllDirectory( cookie_deps_path );
#endif
return FALSE;
}

Expand Down
9 changes: 7 additions & 2 deletions src/core/chuck_dl.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -3011,11 +3011,16 @@ extern "C"
void *dlopen( const char *path, int mode )
{
#ifndef __CHUNREAL_ENGINE__
return (void *)LoadLibrary(path);
// 1.5.4.0 (ge) change from LoadLibrary to LoadLibraryEx to specific
// LOAD_LIBRARY_SEARCH_DEFAULT_DIRS -- this is needed, apparently,
// to take directories added by AddDllDirectory() into account, which
// is needed to load DLL dependencies of chugins...
// https://learn.microsoft.com/en-us/windows/win32/api/libloaderapi/nf-libloaderapi-adddlldirectory
return (void *)LoadLibraryEx( path, NULL, LOAD_LIBRARY_SEARCH_DEFAULT_DIRS );
#else
// 1.5.0.0 (ge) | #chunreal; explicitly call ASCII version
// the build envirnment seems to force UNICODE
return (void *)LoadLibraryA(path);
return (void *)LoadLibraryExA( path, NULL, LOAD_LIBRARY_SEARCH_DEFAULT_DIRS );
#endif
}

Expand Down
6 changes: 3 additions & 3 deletions src/core/chuck_type.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -735,9 +735,9 @@ t_CKBOOL type_engine_init( Chuck_Carrier * carrier )

return TRUE;

error:
EM_error2( 0, "(internal error) during type initialization..." );
EM_error2( 0, "...bailing out; please contact the ChucK Team" );
// error:
// EM_error2( 0, "(internal error) during type initialization..." );
// EM_error2( 0, "...bailing out; please contact the ChucK Team" );

return FALSE;
}
Expand Down

0 comments on commit 0696cd8

Please sign in to comment.