2008-12-08 05:30:24 +00:00
// Copyright (C) 2003-2008 Dolphin Project.
// This program is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation, version 2.0.
// This program is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License 2.0 for more details.
// A copy of the GPL 2.0 should have been included with the program.
// If not, see http://www.gnu.org/licenses/
// Official SVN repository and contact information can be found at
// http://code.google.com/p/dolphin-emu/
# include <string.h>
# ifdef _WIN32
# include <windows.h>
# else
# include <dlfcn.h>
# include <stdio.h>
# endif
# include "Common.h"
2008-12-25 15:56:36 +00:00
# include "FileUtil.h"
2008-12-08 05:30:24 +00:00
# include "StringUtil.h"
# include "DynamicLibrary.h"
DynamicLibrary : : DynamicLibrary ( )
{
library = 0 ;
}
std : : string GetLastErrorAsString ( )
{
2008-12-17 15:34:27 +00:00
# ifdef _WIN32
2008-12-25 15:56:36 +00:00
LPVOID lpMsgBuf = 0 ;
2008-12-08 05:30:24 +00:00
DWORD error = GetLastError ( ) ;
FormatMessage (
FORMAT_MESSAGE_ALLOCATE_BUFFER | FORMAT_MESSAGE_FROM_SYSTEM ,
NULL ,
error ,
MAKELANGID ( LANG_NEUTRAL , SUBLANG_DEFAULT ) , // Default language
( LPTSTR ) & lpMsgBuf ,
0 , NULL ) ;
std : : string s ;
if ( lpMsgBuf )
{
s = ( ( char * ) lpMsgBuf ) ;
LocalFree ( lpMsgBuf ) ;
} else {
s = StringFromFormat ( " (unknown error %08x) " , error ) ;
}
return s ;
2008-12-17 15:34:27 +00:00
# else
static std : : string errstr ;
char * tmp = dlerror ( ) ;
if ( tmp )
errstr = tmp ;
return errstr ;
2008-12-08 05:30:24 +00:00
# endif
2008-12-17 16:24:03 +00:00
}
2008-12-25 15:56:36 +00:00
// Loading means loading the dll with LoadLibrary() to get an instance to the dll.
// This is done when Dolphin is started to determine which dlls are good, and
// before opening the Config and Debugging windows from Plugin.cpp and
// before opening the dll for running the emulation in Video_...cpp in Core.
// Since this is fairly slow, TODO: think about implementing some sort of cache.
2008-12-08 05:30:24 +00:00
int DynamicLibrary : : Load ( const char * filename )
{
if ( ! filename | | strlen ( filename ) = = 0 )
{
LOG ( MASTER_LOG , " Missing filename of dynamic library to load " ) ;
2008-12-17 15:34:27 +00:00
PanicAlert ( " Missing filename of dynamic library to load " ) ;
2008-12-08 05:30:24 +00:00
return 0 ;
}
LOG ( MASTER_LOG , " Trying to load library %s " , filename ) ;
if ( IsLoaded ( ) )
{
LOG ( MASTER_LOG , " Trying to load already loaded library %s " , filename ) ;
return 2 ;
}
# ifdef _WIN32
library = LoadLibrary ( filename ) ;
2008-12-17 15:34:27 +00:00
# else
library = dlopen ( filename , RTLD_NOW | RTLD_LOCAL ) ;
# endif
2008-12-25 15:56:36 +00:00
if ( ! library )
{
2008-12-08 05:30:24 +00:00
LOG ( MASTER_LOG , " Error loading DLL %s: %s " , filename , GetLastErrorAsString ( ) . c_str ( ) ) ;
2008-12-25 15:56:36 +00:00
if ( File : : Exists ( filename ) )
{
PanicAlert ( " Error loading DLL %s: %s \n \n Are you missing SDL.DLL or another file that this plugin may depend on? " , filename , GetLastErrorAsString ( ) . c_str ( ) ) ;
}
else
{
PanicAlert ( " Error loading DLL %s: %s \n " , filename , GetLastErrorAsString ( ) . c_str ( ) ) ;
}
2008-12-08 05:30:24 +00:00
return 0 ;
}
2008-12-17 15:34:27 +00:00
2008-12-08 05:30:24 +00:00
library_file = filename ;
return 1 ;
}
2008-12-17 15:34:27 +00:00
int DynamicLibrary : : Unload ( )
2008-12-08 05:30:24 +00:00
{
2008-12-17 15:34:27 +00:00
int retval ;
if ( ! IsLoaded ( ) ) {
PanicAlert ( " Error unloading DLL %s: not loaded " , library_file . c_str ( ) ) ;
return 0 ;
}
2008-12-08 05:30:24 +00:00
# ifdef _WIN32
2008-12-17 18:20:41 +00:00
retval = FreeLibrary ( library ) ;
2008-12-08 05:30:24 +00:00
# else
2008-12-17 17:49:38 +00:00
retval = dlclose ( library ) ? 0 : 1 ;
2008-12-08 05:30:24 +00:00
# endif
2008-12-17 15:34:27 +00:00
if ( ! retval ) {
PanicAlert ( " Error unloading DLL %s: %s " , library_file . c_str ( ) ,
GetLastErrorAsString ( ) . c_str ( ) ) ;
}
library = 0 ;
return retval ;
2008-12-08 05:30:24 +00:00
}
void * DynamicLibrary : : Get ( const char * funcname ) const
{
void * retval ;
if ( ! library )
{
2008-12-25 15:56:36 +00:00
PanicAlert ( " Can't find function %s - Library not loaded. " ) ;
return NULL ;
2008-12-08 05:30:24 +00:00
}
2008-12-17 15:34:27 +00:00
# ifdef _WIN32
2008-12-08 05:30:24 +00:00
retval = GetProcAddress ( library , funcname ) ;
# else
retval = dlsym ( library , funcname ) ;
2008-12-17 15:34:27 +00:00
# endif
2008-12-08 05:30:24 +00:00
2008-12-17 15:34:27 +00:00
if ( ! retval ) {
2008-12-25 15:56:36 +00:00
LOG ( MASTER_LOG , " Symbol %s missing in %s (error: %s) \n " , funcname , library_file . c_str ( ) , GetLastErrorAsString ( ) . c_str ( ) ) ;
PanicAlert ( " Symbol %s missing in %s (error: %s) \n " , funcname , library_file . c_str ( ) , GetLastErrorAsString ( ) . c_str ( ) ) ;
2008-12-08 05:30:24 +00:00
}
2008-12-17 15:34:27 +00:00
2008-12-08 05:30:24 +00:00
return retval ;
}