Skip to content

Evolution of the Plugin Code

Marco BARNIG edited this page Dec 18, 2019 · 9 revisions

This chapter is referenced by the the tutorial lesson 9 (NanoPlugin) and provides additional information about the Orthanc plugin development.

There a three ways to develop an Orthanc plugin with the Orthanc SDK:

  • by including OrthancCPlugin.h
  • by including OrthancPluginCppWrapper.h
  • by installing and configuring the Orthanc FrameWork

1. OrthancCPlugin.h

Examples

Minimal Code for a plugin

CMakeLists.txt

cmake_minimum_required(VERSION 2.8)   
project(Plugin1)   
set(SAMPLES_ROOT ${CMAKE_SOURCE_DIR}/..)   
include(${SAMPLES_ROOT}/Common/OrthancPlugins.cmake)   
add_library(Plugin1 SHARED Plugin1.cpp)   

Plugin1.cpp

#include <orthanc/OrthancCPlugin.h>  
#include <string>   
static OrthancPluginContext* context_ = NULL;   
ORTHANC_PLUGINS_API OrthancPluginErrorCode Hello1(OrthancPluginRestOutput* output,    
  const char* url, const OrthancPluginHttpRequest* request) {     
  std::string HtmlCode = "<html>\n<head>\n<title>Plugin1</title>\n</head>\n<body>\n<h2>Hello1 Orthanc</h2>\n</body>\n</html>\n";    
  OrthancPluginAnswerBuffer(context_, output, HtmlCode.c_str(), HtmlCode.length(), "text/html");    
  return OrthancPluginErrorCode_Success; }   

extern "C"    
{    
  ORTHANC_PLUGINS_API int32_t OrthancPluginInitialize(OrthancPluginContext* context) {     
    context_ = context;    
    OrthancPluginSetDescription(context, "Orthanc Plugin1 Test with SDK OrthancPlugin.h");   
    OrthancPluginRegisterRestCallback(context, "/hello1", Hello1);`   
    return 0; }
  ORTHANC_PLUGINS_API void OrthancPluginFinalize(){      
    OrthancPluginLogInfo(context_, "Plugin1 is finalizing") }    
  ORTHANC_PLUGINS_API const char* OrthancPluginGetName() {     
    return "Plugin1"; }   
  ORTHANC_PLUGINS_API const char* OrthancPluginGetVersion() {    
    return "1.0.0"; }  
} 

Building (static linking)

  1. Clone the Orthanc repository from BitBucket on your Linux development system
  2. Add the Plugin1 folder with your code inside the Orthanc/Plugins/Samples/ folder
  3. Run the following commands inside the folder Plugin1
mkdir Build    
cd Build  
cmake -DSTATIC_BUILD=ON -DCMAKE_BUILD_TYPE=Release ../    
make 

Results

Library libPlugin1.so : 16.768 bytes

2. OrthancPluginCppWrapper.h

The OrthancPluginCppWrapper includes the OrthancCPlugin code. The wrapper uses the namespace OrthancPlugins. The defined classes, methods and variables are called with the prefix OrtHancPlugins::.

Examples of plugins

Minimal Code for a plugin

CMakeLists.txt

cmake_minimum_required(VERSION 2.8)    
project(Plugin2)   
SET(STATIC_BUILD OFF CACHE BOOL "Static build of the third-party libraries (necessary for Windows)")  
SET(ALLOW_DOWNLOADS OFF CACHE BOOL "Allow CMake to download packages")    
SET(USE_SYSTEM_JSONCPP ON CACHE BOOL "Use the system version of JsonCpp")   
SET(USE_SYSTEM_BOOST ON CACHE BOOL "Use the system version of boost")    
set(SAMPLES_ROOT ${CMAKE_SOURCE_DIR}/..)   
include(${CMAKE_SOURCE_DIR}/../Common/OrthancPlugins.cmake)  
include(${ORTHANC_ROOT}/Resources/CMake/JsonCppConfiguration.cmake)   
include(${ORTHANC_ROOT}/Resources/CMake/BoostConfiguration.cmake)  
add_library(Plugin2 SHARED    
 Plugin2.cpp    
 ${CMAKE_SOURCE_DIR}/../Common/OrthancPluginCppWrapper.cpp    
 ${JSONCPP_SOURCES}     
 ${BOOST_SOURCES}    
 )  
add_definitions(-DHAS_ORTHANC_EXCEPTION=0) 

Plugin2.cpp

#include "../Samples/Common/OrthancPluginCppWrapper.h"    
#include <string>     
void Hello2(OrthancPluginRestOutput* output,     
  const char* url, const OrthancPluginHttpRequest* request) {    
  OrthancPluginContext* context = OrthancPlugins::GetGlobalContext();    
  std::string HtmlCode = "<html>\n<head>\n<title>Plugin2</title>\n</head>\n<body>\n<h2>Hello2 Orthanc</h2>\n</body>\n</html>\n";     
OrthancPluginAnswerBuffer(context, output, HtmlCode.c_str(), HtmlCode.length(), "text/html");     

extern "C"   
{    
  ORTHANC_PLUGINS_API int32_t OrthancPluginInitialize(OrthancPluginContext* context) {    
    OrthancPlugins::SetGlobalContext(context);    
    OrthancPluginSetDescription(context, "Orthanc Plugin Test with SDK OrthancPluginCppWrapper.h");   
    OrthancPlugins::RegisterRestCallback<Hello2>("/hello2", true);    
    return 0; }    
  ORTHANC_PLUGINS_API void OrthancPluginFinalize() {    
     OrthancPlugins::LogInfo("Plugin2 is finalizing"); }    
  ORTHANC_PLUGINS_API const char* OrthancPluginGetName() {   
    return "Plugin2"; }    
  ORTHANC_PLUGINS_API const char* OrthancPluginGetVersion() {    
    return "1.0.0"; }  
}   

Compare the above scripts with those of Plugin1 to see the differences. The main changes are related to the use of :

  • OrthancPlugins::SetGlobalContext(context)
  • OrthancPlugins::RegisterRestCallback()
  • OrthancPlugins::LogInfo()

Building

  1. Clone the Orthanc repository from BitBucket on your Linux development system
  2. Add the Plugin2 folder inside the Orthanc/Plugins/Samples/ folder
  3. Run the following commands inside the folder Plugin2
mkdir Build     
cd Build    
cmake -DSTATIC_BUILD=ON -DCMAKE_BUILD_TYPE=Release ../  
make 

Results

  • Library libPlugin2.so : 1.602.584 bytes

3. OrthancFrameWork

Examples

Minimal Code for a plugin

Resources/SyncOrthancFolder.py

This maintenance script loads the latest version of the Orthanc source code into the Build folder. The script is executed by the execute-process command in the following CMakeLists.txt.

CMakeLists.txt

cmake_minimum_required(VERSION 2.8)     
project(Plugin3)     
set(ORTHANC_FRAMEWORK_VERSION "mainline")    
set(ORTHANC_FRAMEWORK_SOURCE "hg" CACHE STRING "Source of the Orthanc source code (can be hg, archive, we or path)")  
set(USE_SYSTEM_ORTHANC_SDK ON CACHE BOOL "Use the system version of the Orthanc plugin SDK")    
execute_process(   
  COMMAND   
  /usr/bin/python ${CMAKE_SOURCE_DIR}/Resources/SyncOrthancFolder.py   
)  
include(${CMAKE_SOURCE_DIR}/Resources/Orthanc/DownloadOrthancFramework.cmake)   
set(ORTHANC_FRAMEWORK_PLUGIN ON)   
include(${ORTHANC_ROOT}/Resources/CMake/OrthancFrameworkParameters.cmake)   
set(ENABLE_LOCALE ON)   
set(ENABLE_MODULE_IMAGES OFF CACHE INTERNAL "Enable module for image processing")   
set(ENABLE_MODULE_JOBS OFF CACHE INTERNAL "Enable module for jobs")    
set(ENABLE_MODULE_DICOM OFF CACHE INTERNAL "Enable module for DICOM handling")    
include(${ORTHANC_ROOT}/Resources/CMake/OrthancFrameworkConfiguration.cmake)   
include_directories(   
${ORTHANC_ROOT}   
${ORTHANC_ROOT}/Core   
${ORTHANC_ROOT}/Plugins/Include   
)   
add_definitions(    
  -DHAS_ORTHANC_EXCEPTION=1   
  -DORTHANC_ENABLE_LOGGING_PLUGIN=1   
)   
set(CORE_SOURCES    
  ${ORTHANC_ROOT}/Plugins/Samples/Common/OrthancPluginCppWrapper.cpp    
  ${ORTHANC_CORE_SOURCES}    
)     
add_library(Plugin3 SHARED     
  ${CORE_SOURCES}   
  ${CMAKE_SOURCE_DIR}/Plugin3.cpp   
  ${AUTOGENERATED_SOURCES   
)    

PluginTest3.cpp

#include <Plugins/Samples/Common/OrthancPluginCppWrapper.h>    
#include <Core/SystemToolbox.h>      
#include <Core/Toolbox.h>     
#include <Core/Logging.h>     
#include <string>     
void Hello3(OrthancPluginRestOutput* output,   
  const char* url, const OrthancPluginHttpRequest* request) {     
  OrthancPluginContext* context = OrthancPlugins::GetGlobalContext();     
  std::string HtmlCode = "<html>\n<head>\n<title>MiniPlugin</title>\n</head>\n<body>\n<h2>Hello3 Orthanc</h2>\n</body>\n</html>\n";    
  OrthancPluginAnswerBuffer(context, output, HtmlCode.c_str(), HtmlCode.length(), "text/html");   
}   

extern "C"    
{      
  ORTHANC_PLUGINS_API int32_t OrthancPluginInitialize(OrthancPluginContext* context) {    
    Orthanc::Logging::Initialize(context);    
    OrthancPlugins::SetGlobalContext(context);    
    OrthancPluginSetDescription(context, "Orthanc Plugin Test with Framework");   
    OrthancPlugins::RegisterRestCallback<Hello3>("/hello3", true);   
    return 0; }    
  ORTHANC_PLUGINS_API void OrthancPluginFinalize() {   
    LOG(INFO) << "Plugin3 is finalizing"; }   
  ORTHANC_PLUGINS_API const char* OrthancPluginGetName() {   
    return "Plugin3"; }    
  ORTHANC_PLUGINS_API const char* OrthancPluginGetVersion() {    
    return "1.0.0"; }   
}  

If you compare the above scripts with those of Plugin2 you see the following main changes:

  • inclusion of Orthanc Core files
  • use of Orthanc::Logging::Initialize(context) to enable the user-friendly logging system

Building

  1. Add the Plugin3 folder anywhere in your Docker development container
  2. Run the following commands inside the folder Plugin3
mkdir Build     
cd Build    
cmake -DSTATIC_BUILD=ON -DCMAKE_BUILD_TYPE=Release ../   
make 

Results

  • Library libPlugin3.so : 3.617.816 bytes

Notes

The following figure shows the three plugins installed inside the RadioLogicArchive.

orthanc-plugins

In our small tutorial we use the third way, the most advanced process using the framework, to develop some plugins for Orthanc.

Clone this wiki locally