From b9db890ebc8a5c900439c23cf7bdaa44721a35c3 Mon Sep 17 00:00:00 2001 From: Brad King Date: Wed, 11 Sep 2002 09:54:03 -0400 Subject: [PATCH] ENH: Pointer-to-function to pointer-to-data casts are not even allowed in strict C. Re-implemented this conversion in pure C++ using a casting trick with an extra level of indirection. --- Source/CMakeLists.txt | 1 - Source/cmDynamicLoader.cxx | 70 +++++++++++++++++----- Source/cmDynamicLoader.h | 12 +--- Source/cmDynamicLoaderC.c | 118 ------------------------------------- 4 files changed, 58 insertions(+), 143 deletions(-) delete mode 100644 Source/cmDynamicLoaderC.c diff --git a/Source/CMakeLists.txt b/Source/CMakeLists.txt index 06bd3b6e8..e0dc7e464 100644 --- a/Source/CMakeLists.txt +++ b/Source/CMakeLists.txt @@ -10,7 +10,6 @@ cmSourceFile.cxx cmSystemTools.cxx cmDirectory.cxx cmDynamicLoader.cxx -cmDynamicLoaderC.c cmCommands.cxx cmTarget.cxx cmCustomCommand.cxx diff --git a/Source/cmDynamicLoader.cxx b/Source/cmDynamicLoader.cxx index 891f4c292..05431767a 100644 --- a/Source/cmDynamicLoader.cxx +++ b/Source/cmDynamicLoader.cxx @@ -16,20 +16,7 @@ =========================================================================*/ #include "cmDynamicLoader.h" -extern "C" -{ -cmDynamicLoaderFunction cmDynamicLoaderGetSymbolAddress(cmLibHandle, - const char*); -} - -// Dispatch to C implementation. -cmDynamicLoaderFunction cmDynamicLoader::GetSymbolAddress(cmLibHandle lib, - const char* sym) -{ - return cmDynamicLoaderGetSymbolAddress(lib, sym); -} - -// This file is actually 4 different implementations. +// This file is actually several different implementations. // 1. HP machines which uses shl_load // 2. Apple OSX which uses NSLinkModule // 3. Windows which uses LoadLibrary @@ -53,6 +40,19 @@ int cmDynamicLoader::CloseLibrary(cmLibHandle lib) return 0; } +cmDynamicLoaderFunction +cmDynamicLoader::GetSymbolAddress(cmLibHandle lib, const char* sym) +{ + void* addr; + int status; + + status = shl_findsym (&lib, sym, TYPE_PROCEDURE, &addr); + void* result = (status < 0) ? (void*)0 : addr; + + // Hack to cast pointer-to-data to pointer-to-function. + return *reinterpret_cast(&result); +} + const char* cmDynamicLoader::LibPrefix() { return "lib"; @@ -92,6 +92,22 @@ int cmDynamicLoader::CloseLibrary(cmLibHandle lib) return 0; } +cmDynamicLoaderFunction +cmDynamicLoader::GetSymbolAddress(cmLibHandle lib, const char* sym) +{ + void *result=0; + if(NSIsSymbolNameDefined(sym)) + { + NSSymbol symbol= NSLookupAndBindSymbol(sym); + if(symbol) + { + result = NSAddressOfSymbol(symbol); + } + } + // Hack to cast pointer-to-data to pointer-to-function. + return *reinterpret_cast(&result); +} + const char* cmDynamicLoader::LibPrefix() { return ""; @@ -136,6 +152,23 @@ int cmDynamicLoader::CloseLibrary(cmLibHandle lib) return (int)FreeLibrary(lib); } +cmDynamicLoaderFunction +cmDynamicLoader::GetSymbolAddress(cmLibHandle lib, const char* sym) +{ + void* result = 0; +#ifdef UNICODE + wchar_t *wsym = new wchar_t [mbstowcs(NULL, sym, 32000)]; + mbstowcs(wsym, sym, 32000); + void *ret = GetProcAddress(lib, wsym); + delete [] wsym; + result = ret; +#else + result = GetProcAddress(lib, sym); +#endif + // Hack to cast pointer-to-data to pointer-to-function. + return *reinterpret_cast(&result); +} + const char* cmDynamicLoader::LibPrefix() { return ""; @@ -188,6 +221,15 @@ int cmDynamicLoader::CloseLibrary(cmLibHandle lib) return (int)dlclose(lib); } +cmDynamicLoaderFunction +cmDynamicLoader::GetSymbolAddress(cmLibHandle lib, const char* sym) +{ + void* result = dlsym(lib, sym); + + // Hack to cast pointer-to-data to pointer-to-function. + return *reinterpret_cast(&result); +} + const char* cmDynamicLoader::LibPrefix() { return "lib"; diff --git a/Source/cmDynamicLoader.h b/Source/cmDynamicLoader.h index 7c49f9097..39385286a 100644 --- a/Source/cmDynamicLoader.h +++ b/Source/cmDynamicLoader.h @@ -37,16 +37,8 @@ typedef void* cmLibHandle; #endif -// C++ Does not allow casts from pointer-to-data types to -// pointer-to-function types. However, the return type from each -// platform's symbol lookup implementation is void*. We need to hide -// the cast from void* to a pointer-to-function type in C code. The -// implementation of cmDynamicLoader::GetSymbolAddress simply calls a -// C-based implementation in cmDynamicLoaderC.c. This -// cmDynamicLoaderFunction type is the return type of -// cmDynamicLoader::GetSymbolAddress and can be cast to any other -// pointer-to-function type safely in C++. -extern "C" { typedef void (*cmDynamicLoaderFunction)(); } +// Return type from cmDynamicLoader::GetSymbolAddress. +typedef void (*cmDynamicLoaderFunction)(); class cmDynamicLoader { diff --git a/Source/cmDynamicLoaderC.c b/Source/cmDynamicLoaderC.c deleted file mode 100644 index 032a6136f..000000000 --- a/Source/cmDynamicLoaderC.c +++ /dev/null @@ -1,118 +0,0 @@ -/*========================================================================= - - Program: Insight Segmentation & Registration Toolkit - Module: $RCSfile$ - Language: C++ - Date: $Date$ - Version: $Revision$ - - Copyright (c) 2002 Insight Consortium. All rights reserved. - See ITKCopyright.txt or http://www.itk.org/HTML/Copyright.htm for details. - - This software is distributed WITHOUT ANY WARRANTY; without even - the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR - PURPOSE. See the above copyright notices for more information. - -=========================================================================*/ - -/* - * This file is actually 4 different implementations. - * 1. HP machines which uses shl_load - * 2. Apple OSX which uses NSLinkModule - * 3. Windows which uses LoadLibrary - * 4. Most unix systems which use dlopen (default ) - * Each part of the ifdef contains a complete implementation for - * the static methods of cmDynamicLoader. - */ - -/* Ugly stuff for library handles. They are different on several - different OS's */ -#if defined(__hpux) -# include - typedef shl_t cmLibHandle; -#elif defined(_WIN32) - #include - typedef HMODULE cmLibHandle; -#else - typedef void* cmLibHandle; -#endif - -typedef void (*cmDynamicLoaderFunction)(); - -/* --------------------------------------------------------------- */ -/* 1. Implementation for HPUX machines */ -#ifdef __hpux -#define CMDYNAMICLOADER_DEFINED 1 -#include - -cmDynamicLoaderFunction cmDynamicLoaderGetSymbolAddress(cmLibHandle lib, - const char* sym) -{ - void* addr; - int status; - - status = shl_findsym (&lib, sym, TYPE_PROCEDURE, &addr); - return (cmDynamicLoaderFunction)((status < 0) ? (void*)0 : addr); -} -#endif - - -/* --------------------------------------------------------------- */ -/* 2. Implementation for Darwin (including OSX) Machines */ - -#ifdef __APPLE__ -#define CMDYNAMICLOADER_DEFINED -#include - -cmDynamicLoaderFunction cmDynamicLoaderGetSymbolAddress(cmLibHandle lib, - const char* sym) -{ - void *result=0; - if(NSIsSymbolNameDefined(sym)) - { - NSSymbol symbol= NSLookupAndBindSymbol(sym); - if(symbol) - { - result = NSAddressOfSymbol(symbol); - } - } - return (cmDynamicLoaderFunction)result; -} -#endif - - -/* --------------------------------------------------------------- */ -/* 3. Implementation for Windows win32 code */ -#ifdef _WIN32 -#include -#define CMDYNAMICLOADER_DEFINED 1 - -cmDynamicLoaderFunction cmDynamicLoaderGetSymbolAddress(cmLibHandle lib, - const char* sym) -{ -#ifdef UNICODE - wchar_t *wsym = new wchar_t [mbstowcs(NULL, sym, 32000)]; - mbstowcs(wsym, sym, 32000); - void *ret = GetProcAddress(lib, wsym); - delete [] wsym; - return (cmDynamicLoaderFunction)ret; -#else - return (cmDynamicLoaderFunction)GetProcAddress(lib, sym); -#endif -} -#endif - -/* --------------------------------------------------------------- */ -/* 4. Implementation for default UNIX machines. - if nothing has been defined then use this */ -#ifndef CMDYNAMICLOADER_DEFINED -#define CMDYNAMICLOADER_DEFINED -/* Setup for most unix machines */ -#include - -cmDynamicLoaderFunction cmDynamicLoaderGetSymbolAddress(cmLibHandle lib, - const char* sym) -{ - return (cmDynamicLoaderFunction)dlsym(lib, sym); -} -#endif