Browse Source

ERR: Cast from pointer-to-data to pointer-to-function is not allowed in C++. The cast needed by cmDynamicLoader::GetSymbolAddress is now hidden in a C file.

Brad King 23 years ago
parent
commit
820088cefc
4 changed files with 142 additions and 43 deletions
  1. 1 0
      Source/CMakeLists.txt
  2. 14 42
      Source/cmDynamicLoader.cxx
  3. 12 1
      Source/cmDynamicLoader.h
  4. 115 0
      Source/cmDynamicLoaderC.c

+ 1 - 0
Source/CMakeLists.txt

@@ -10,6 +10,7 @@ cmSourceFile.cxx
 cmSystemTools.cxx
 cmDirectory.cxx
 cmDynamicLoader.cxx
+cmDynamicLoaderC.c
 cmCommands.cxx
 cmTarget.cxx
 cmCustomCommand.cxx

+ 14 - 42
Source/cmDynamicLoader.cxx

@@ -16,7 +16,20 @@
 =========================================================================*/
 #include "cmDynamicLoader.h"
 
-// This file is actually 3 different implementations.
+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.
 // 1. HP machines which uses shl_load
 // 2. Apple OSX which uses NSLinkModule
 // 3. Windows which uses LoadLibrary
@@ -40,15 +53,6 @@ int cmDynamicLoader::CloseLibrary(cmLibHandle lib)
   return 0;
 }
 
-void* cmDynamicLoader::GetSymbolAddress(cmLibHandle lib, const char* sym)
-{ 
-  void* addr;
-  int status;
-  
-  status = shl_findsym (&lib, sym, TYPE_PROCEDURE, &addr);
-  return (status < 0) ? (void*)0 : addr;
-}
-
 const char* cmDynamicLoader::LibPrefix()
 { 
   return "lib";
@@ -88,20 +92,6 @@ int cmDynamicLoader::CloseLibrary(cmLibHandle lib)
   return 0;
 }
 
-void* cmDynamicLoader::GetSymbolAddress(cmLibHandle lib, const char* sym)
-{
-  void *result=0;
-  if(NSIsSymbolNameDefined(sym))
-    {
-    NSSymbol symbol= NSLookupAndBindSymbol(sym);
-    if(symbol)
-      {
-      result = NSAddressOfSymbol(symbol);
-      }
-    }
-  return result;
-}
-
 const char* cmDynamicLoader::LibPrefix()
 {
   return "";
@@ -146,19 +136,6 @@ int cmDynamicLoader::CloseLibrary(cmLibHandle lib)
   return (int)FreeLibrary(lib);
 }
 
-void* cmDynamicLoader::GetSymbolAddress(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 ret;
-#else
-  return GetProcAddress(lib, sym);
-#endif
-}
-
 const char* cmDynamicLoader::LibPrefix()
 { 
   return "";
@@ -211,11 +188,6 @@ int cmDynamicLoader::CloseLibrary(cmLibHandle lib)
   return (int)dlclose(lib);
 }
 
-void* cmDynamicLoader::GetSymbolAddress(cmLibHandle lib, const char* sym)
-{ 
-  return dlsym(lib, sym);
-}
-
 const char* cmDynamicLoader::LibPrefix()
 { 
   return "lib";

+ 12 - 1
Source/cmDynamicLoader.h

@@ -37,6 +37,17 @@
   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)(); }
+
 class cmDynamicLoader
 {
 public:
@@ -53,7 +64,7 @@ public:
   
   // Description:
   // Find the address of the symbol in the given library
-  static void* GetSymbolAddress(cmLibHandle, const char*);
+  static cmDynamicLoaderFunction GetSymbolAddress(cmLibHandle, const char*);
 
   // Description:
   // Return the library prefix for the given architecture

+ 115 - 0
Source/cmDynamicLoaderC.c

@@ -0,0 +1,115 @@
+/*=========================================================================
+
+  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 <dl.h>
+  typedef shl_t cmLibHandle;
+#elif defined(_WIN32)
+  #include <windows.h>
+  typedef HMODULE cmLibHandle;
+#else
+  typedef void* cmLibHandle;
+#endif
+
+typedef void (*cmDynamicLoaderFunction)();
+
+// ---------------------------------------------------------------
+// 1. Implementation for HPUX  machines
+#ifdef __hpux
+#define CMDYNAMICLOADER_DEFINED 1
+#include <dl.h>
+
+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 <mach-o/dyld.h>
+
+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 <windows.h>
+#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 <dlfcn.h>
+
+cmDynamicLoaderFunction cmDynamicLoaderGetSymbolAddress(cmLibHandle lib,
+                                                        const char* sym)
+{ 
+  return (cmDynamicLoaderFunction)dlsym(lib, sym);
+}
+#endif