Skip to content

Instantly share code, notes, and snippets.

@PsichiX
Created June 2, 2017 16:33
Show Gist options
  • Save PsichiX/b328efe47c86e7b151198e5fc7395427 to your computer and use it in GitHub Desktop.
Save PsichiX/b328efe47c86e7b151198e5fc7395427 to your computer and use it in GitHub Desktop.
Shared Library Manager
#include "library.h"
#ifdef BUILD_LINUX
#include <dlfcn.h>
#endif
#ifdef BUILD_WIN
#include <windows.h>
#endif
#include <map>
struct Handle
{
void* value;
int counter;
};
std::map< std::string, Handle > g_handles;
void* loadLibrary( const std::string& path )
{
if( g_handles.count( path ) )
{
auto& h = g_handles[ path ];
++h.counter;
return h.value;
}
void* handle = nullptr;
#ifdef BUILD_LINUX
handle = dlopen( (path + ".so").c_str(), RTLD_LAZY );
if( !handle )
handle = dlopen( path.c_str(), RTLD_LAZY );
#endif
#ifdef BUILD_WIN
handle = LoadLibrary( (path + ".dll").c_str() );
if( !handle )
handle = LoadLibrary( path.c_str() );
#endif
if( handle )
{
auto& h = g_handles[ path ];
h.counter = 1;
h.value = handle;
}
return handle;
}
void* getFunction( void* handle, const std::string& name )
{
#ifdef BUILD_LINUX
return dlsym( handle, name.c_str() );
#endif
#ifdef BUILD_WIN
return (void*)GetProcAddress( (HINSTANCE)handle, name.c_str() );
#endif
}
int closeLibrary( void* handle )
{
for( auto& kv : g_handles )
{
if( kv.second.value == handle )
{
if( --kv.second.counter > 0 )
return 0;
else
{
g_handles.erase( kv.first );
#ifdef BUILD_LINUX
return dlclose( handle );
#endif
#ifdef BUILD_WIN
return FreeLibrary( (HINSTANCE)handle );
#endif
}
}
}
return -1;
}
#ifndef __LIBRARY_H__
#define __LIBRARY_H__
#include <string>
void* loadLibrary( const std::string& path );
void* getFunction( void* handle, const std::string& name );
int closeLibrary( void* handle );
#endif
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment