Skip to content

Commit

Permalink
move windows-specific dll deps logic to windows dlopen()
Browse files Browse the repository at this point in the history
  • Loading branch information
gewang committed Nov 4, 2024
1 parent 59f6852 commit 18a9c64
Show file tree
Hide file tree
Showing 2 changed files with 51 additions and 35 deletions.
33 changes: 4 additions & 29 deletions src/core/chuck_compile.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1623,8 +1623,6 @@ 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 @@ -1636,24 +1634,8 @@ 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( platformPath.c_str(), CK_QUERY_FUNC, TRUE) )
if( dll->load( path.c_str(), CK_QUERY_FUNC, TRUE) )
{
// probe it
dll->probe();
Expand Down Expand Up @@ -1722,11 +1704,7 @@ 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 @@ -1735,11 +1713,8 @@ 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 home :(
return FALSE;
}

Expand Down
53 changes: 47 additions & 6 deletions src/core/chuck_dl.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -983,14 +983,18 @@ Chuck_Carrier * Chuck_DL_Query::carrier() const { return m_carrier; }
//-----------------------------------------------------------------------------
t_CKBOOL Chuck_DLL::load( const char * filename, const char * func, t_CKBOOL lazy )
{
// return value
t_CKBOOL ret = TRUE;

// open
m_handle = dlopen( filename, lazy ? RTLD_LAZY : RTLD_NOW );

// still not there
if( !m_handle )
{
m_last_error = dlerror();
return FALSE;
ret = FALSE;
goto cleanup;
}

// save the filename
Expand All @@ -1000,9 +1004,20 @@ t_CKBOOL Chuck_DLL::load( const char * filename, const char * func, t_CKBOOL laz

// if not lazy, do it
if( !lazy && !this->query() )
return FALSE;
{
// clean up the handle | 1.5.4.1 (ge) added here
dlclose( m_handle );
m_handle = NULL;

return TRUE;
// FYI last error should be set from within query()
ret = FALSE;
goto cleanup;
}

cleanup:

// return
return ret;
}


Expand Down Expand Up @@ -3009,20 +3024,46 @@ extern "C"
#include "Windows/MinWindows.h"
#endif // #ifndef __CHUNREAL_ENGINE__

void *dlopen( const char *path, int mode )
void * dlopen( const char * path, int mode )
{
// return
void * retval = NULL;

// add DLL search path | 1.5.4.0 (ge & nshaheed) added
// (e.g., for chugins that have DLL dependencies)
// 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() );

#ifndef __CHUNREAL_ENGINE__
// 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 );
retval = (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 *)LoadLibraryExA( path, NULL, LOAD_LIBRARY_SEARCH_DEFAULT_DIRS );
retval = (void *)LoadLibraryExA( path, NULL, LOAD_LIBRARY_SEARCH_DEFAULT_DIRS );
#endif

// undo the AddDllDirectory()
if( cookie_path ) RemoveDllDirectory( cookie_path );
if( cookie_deps_path ) RemoveDllDirectory( cookie_deps_path );

// return
return retval;
}

int dlclose( void *handle )
Expand Down

0 comments on commit 18a9c64

Please sign in to comment.