changeset 885:0570a8c859cb plugins

SharedLibrary class
author Sebastien Jodogne <s.jodogne@gmail.com>
date Sat, 14 Jun 2014 16:53:28 +0200
parents cd8a69aa4093
children 29087d728e0a
files CMakeLists.txt Core/Enumerations.h Core/OrthancException.cpp Core/Toolbox.cpp Core/Toolbox.h Plugins/Engine/DynamicLibrary.cpp Plugins/Engine/DynamicLibrary.h Plugins/Engine/SharedLibrary.cpp Plugins/Engine/SharedLibrary.h UnitTestsSources/PluginsTests.cpp
diffstat 10 files changed, 260 insertions(+), 92 deletions(-) [+]
line wrap: on
line diff
--- a/CMakeLists.txt	Sat Jun 14 16:04:15 2014 +0200
+++ b/CMakeLists.txt	Sat Jun 14 16:53:28 2014 +0200
@@ -115,7 +115,7 @@
   OrthancCppClient/Instance.cpp
   OrthancCppClient/Patient.cpp
 
-  Plugins/Engine/DynamicLibrary.cpp
+  Plugins/Engine/SharedLibrary.cpp
   )
 
 
@@ -170,6 +170,7 @@
   UnitTestsSources/UnitTestsMain.cpp
   UnitTestsSources/ImageProcessingTests.cpp
   UnitTestsSources/JpegLossless.cpp
+  UnitTestsSources/PluginsTests.cpp
   )
 
 
--- a/Core/Enumerations.h	Sat Jun 14 16:04:15 2014 +0200
+++ b/Core/Enumerations.h	Sat Jun 14 16:53:28 2014 +0200
@@ -71,7 +71,8 @@
     ErrorCode_InexistentTag,
     ErrorCode_ReadOnly,
     ErrorCode_IncompatibleImageFormat,
-    ErrorCode_IncompatibleImageSize
+    ErrorCode_IncompatibleImageSize,
+    ErrorCode_SharedLibrary
   };
 
   /**
--- a/Core/OrthancException.cpp	Sat Jun 14 16:04:15 2014 +0200
+++ b/Core/OrthancException.cpp	Sat Jun 14 16:53:28 2014 +0200
@@ -121,6 +121,9 @@
       case ErrorCode_IncompatibleImageFormat:
         return "Incompatible format of the images";
 
+      case ErrorCode_SharedLibrary:
+        return "Error while using a shared library (plugin)";
+
       case ErrorCode_Custom:
       default:
         return "???";
--- a/Core/Toolbox.cpp	Sat Jun 14 16:04:15 2014 +0200
+++ b/Core/Toolbox.cpp	Sat Jun 14 16:53:28 2014 +0200
@@ -845,5 +845,12 @@
       }
     }
   }
+
+
+  bool Toolbox::IsExistingFile(const std::string& path)
+  {
+    return boost::filesystem::exists(path);
+  }
+
 }
 
--- a/Core/Toolbox.h	Sat Jun 14 16:04:15 2014 +0200
+++ b/Core/Toolbox.h	Sat Jun 14 16:53:28 2014 +0200
@@ -130,5 +130,7 @@
                              const std::string& source);
 
     void CreateDirectory(const std::string& path);
+
+    bool IsExistingFile(const std::string& path);
   }
 }
--- a/Plugins/Engine/DynamicLibrary.cpp	Sat Jun 14 16:04:15 2014 +0200
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,41 +0,0 @@
-/**
- * Orthanc - A Lightweight, RESTful DICOM Store
- * Copyright (C) 2012-2014 Medical Physics Department, CHU of Liege,
- * Belgium
- *
- * 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, either version 3 of the
- * License, or (at your option) any later version.
- *
- * In addition, as a special exception, the copyright holders of this
- * program give permission to link the code of its release with the
- * OpenSSL project's "OpenSSL" library (or with modified versions of it
- * that use the same license as the "OpenSSL" library), and distribute
- * the linked executables. You must obey the GNU General Public License
- * in all respects for all of the code used other than "OpenSSL". If you
- * modify file(s) with this exception, you may extend this exception to
- * your version of the file(s), but you are not obligated to do so. If
- * you do not wish to do so, delete this exception statement from your
- * version. If you delete this exception statement from all source files
- * in the program, then also delete it here.
- * 
- * 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 for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program. If not, see <http://www.gnu.org/licenses/>.
- **/
-
-
-#include "DynamicLibrary.h"
-
-namespace Orthanc
-{
-  DynamicLibrary::DynamicLibrary(const std::string& path)
-  {
-
-  }
-}
--- a/Plugins/Engine/DynamicLibrary.h	Sat Jun 14 16:04:15 2014 +0200
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,49 +0,0 @@
-/**
- * Orthanc - A Lightweight, RESTful DICOM Store
- * Copyright (C) 2012-2014 Medical Physics Department, CHU of Liege,
- * Belgium
- *
- * 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, either version 3 of the
- * License, or (at your option) any later version.
- *
- * In addition, as a special exception, the copyright holders of this
- * program give permission to link the code of its release with the
- * OpenSSL project's "OpenSSL" library (or with modified versions of it
- * that use the same license as the "OpenSSL" library), and distribute
- * the linked executables. You must obey the GNU General Public License
- * in all respects for all of the code used other than "OpenSSL". If you
- * modify file(s) with this exception, you may extend this exception to
- * your version of the file(s), but you are not obligated to do so. If
- * you do not wish to do so, delete this exception statement from your
- * version. If you delete this exception statement from all source files
- * in the program, then also delete it here.
- * 
- * 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 for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program. If not, see <http://www.gnu.org/licenses/>.
- **/
-
-
-#pragma once
-
-#include "../../Core/OrthancException.h"
-
-#include <boost/noncopyable.hpp>
-
-namespace Orthanc
-{
-  class DynamicLibrary : boost::noncopyable
-  {
-  private:
-    void *handle_;
-
-  public:
-    DynamicLibrary(const std::string& path);
-  };
-}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/Plugins/Engine/SharedLibrary.cpp	Sat Jun 14 16:53:28 2014 +0200
@@ -0,0 +1,131 @@
+/**
+ * Orthanc - A Lightweight, RESTful DICOM Store
+ * Copyright (C) 2012-2014 Medical Physics Department, CHU of Liege,
+ * Belgium
+ *
+ * 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, either version 3 of the
+ * License, or (at your option) any later version.
+ *
+ * In addition, as a special exception, the copyright holders of this
+ * program give permission to link the code of its release with the
+ * OpenSSL project's "OpenSSL" library (or with modified versions of it
+ * that use the same license as the "OpenSSL" library), and distribute
+ * the linked executables. You must obey the GNU General Public License
+ * in all respects for all of the code used other than "OpenSSL". If you
+ * modify file(s) with this exception, you may extend this exception to
+ * your version of the file(s), but you are not obligated to do so. If
+ * you do not wish to do so, delete this exception statement from your
+ * version. If you delete this exception statement from all source files
+ * in the program, then also delete it here.
+ * 
+ * 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 for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
+ **/
+
+
+#include "SharedLibrary.h"
+
+#include "../../Core/Toolbox.h"
+
+#if defined(_WIN32)
+#include <windows.h>
+#elif defined(__linux)
+#include <dlfcn.h>
+#else
+#error Support your platform here
+#endif
+
+#include <glog/logging.h>
+
+namespace Orthanc
+{
+  SharedLibrary::SharedLibrary(const std::string& path) : handle_(NULL)
+  {
+#if defined(_WIN32)
+    handle_ = ::LoadLibraryA(path.c_str());
+    if (handle == NULL)
+    {
+      LOG(ERROR) << "LoadLibrary(" << path << ") failed: Error " << ::GetLastError();
+      throw OrthancException(ErrorCode_SharedLibrary);
+    }
+
+#elif defined(__linux)
+    handle_ = ::dlopen(path.c_str(), RTLD_NOW);
+    if (handle_ == NULL) 
+    {
+      std::string explanation;
+      const char *tmp = ::dlerror();
+      if (tmp)
+      {
+        explanation = ": Error " + std::string(tmp);
+      }
+
+      LOG(ERROR) << "dlopen(" << path << ") failed" << explanation;
+      throw OrthancException(ErrorCode_SharedLibrary);
+    }
+
+#else
+#error Support your platform here
+#endif   
+  }
+
+  SharedLibrary::~SharedLibrary()
+  {
+    if (handle_)
+    {
+#if defined(_WIN32)
+      ::FreeLibrary((HMODULE)handle_);
+#elif defined(__linux)
+      ::dlclose(handle_);
+#else
+#error Support your platform here
+#endif
+    }
+  }
+
+
+  void* SharedLibrary::GetFunctionInternal(const std::string& name)
+  {
+    if (!handle_)
+    {
+      throw OrthancException(ErrorCode_InternalError);
+    }
+
+#if defined(_WIN32)
+    return ::GetProcAddress((HMODULE)handle_, name.c_str());
+#elif defined(__linux)
+    return ::dlsym(handle_, name.c_str());
+#else
+#error Support your platform here
+#endif
+  }
+
+
+  void* SharedLibrary::GetFunction(const std::string& name)
+  {
+    void* result = GetFunctionInternal(name);
+  
+    if (result == NULL)
+    {
+      LOG(ERROR) << "Shared library does not expose function \"" << name << "\"";
+      throw OrthancException(ErrorCode_SharedLibrary);
+    }
+    else
+    {
+      return result;
+    }
+  }
+
+
+  bool SharedLibrary::HasFunction(const std::string& name)
+  {
+    return GetFunctionInternal(name) != NULL;
+  }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/Plugins/Engine/SharedLibrary.h	Sat Jun 14 16:53:28 2014 +0200
@@ -0,0 +1,57 @@
+/**
+ * Orthanc - A Lightweight, RESTful DICOM Store
+ * Copyright (C) 2012-2014 Medical Physics Department, CHU of Liege,
+ * Belgium
+ *
+ * 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, either version 3 of the
+ * License, or (at your option) any later version.
+ *
+ * In addition, as a special exception, the copyright holders of this
+ * program give permission to link the code of its release with the
+ * OpenSSL project's "OpenSSL" library (or with modified versions of it
+ * that use the same license as the "OpenSSL" library), and distribute
+ * the linked executables. You must obey the GNU General Public License
+ * in all respects for all of the code used other than "OpenSSL". If you
+ * modify file(s) with this exception, you may extend this exception to
+ * your version of the file(s), but you are not obligated to do so. If
+ * you do not wish to do so, delete this exception statement from your
+ * version. If you delete this exception statement from all source files
+ * in the program, then also delete it here.
+ * 
+ * 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 for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
+ **/
+
+
+#pragma once
+
+#include "../../Core/OrthancException.h"
+
+#include <boost/noncopyable.hpp>
+
+namespace Orthanc
+{
+  class SharedLibrary : boost::noncopyable
+  {
+  private:
+    void *handle_;
+
+    void* GetFunctionInternal(const std::string& name);
+
+  public:
+    SharedLibrary(const std::string& path);
+
+    ~SharedLibrary();
+
+    bool HasFunction(const std::string& name);
+
+    void* GetFunction(const std::string& name);
+  };
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/UnitTestsSources/PluginsTests.cpp	Sat Jun 14 16:53:28 2014 +0200
@@ -0,0 +1,56 @@
+/**
+ * Orthanc - A Lightweight, RESTful DICOM Store
+ * Copyright (C) 2012-2014 Medical Physics Department, CHU of Liege,
+ * Belgium
+ *
+ * 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, either version 3 of the
+ * License, or (at your option) any later version.
+ *
+ * In addition, as a special exception, the copyright holders of this
+ * program give permission to link the code of its release with the
+ * OpenSSL project's "OpenSSL" library (or with modified versions of it
+ * that use the same license as the "OpenSSL" library), and distribute
+ * the linked executables. You must obey the GNU General Public License
+ * in all respects for all of the code used other than "OpenSSL". If you
+ * modify file(s) with this exception, you may extend this exception to
+ * your version of the file(s), but you are not obligated to do so. If
+ * you do not wish to do so, delete this exception statement from your
+ * version. If you delete this exception statement from all source files
+ * in the program, then also delete it here.
+ * 
+ * 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 for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
+ **/
+
+
+#include "PrecompiledHeadersUnitTests.h"
+#include "gtest/gtest.h"
+
+#include "../Plugins/Engine/SharedLibrary.h"
+
+using namespace Orthanc;
+
+TEST(SharedLibrary, Basic)
+{
+#if defined(_WIN32)
+#error Support your platform here
+
+#elif defined(__linux)
+  SharedLibrary l("libdl.so");
+  ASSERT_THROW(l.GetFunction("world"), OrthancException);
+  ASSERT_TRUE(l.GetFunction("dlopen") != NULL);
+  ASSERT_TRUE(l.HasFunction("dlclose"));
+  ASSERT_FALSE(l.HasFunction("world"));
+
+#else
+#error Support your platform here
+#endif
+
+}