summaryrefslogtreecommitdiff
path: root/AudioManagerUtilities/include/TAmPluginTemplate.h
blob: 95523f1d47141b3c562048cf783d5ecb6e85afd7 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
/**
 * SPDX license identifier: MPL-2.0
 *
 * Copyright (C) 2012, BMW AG
 *
 * This file is part of GENIVI Project AudioManager.
 *
 * Contributions are licensed to the GENIVI Alliance under one or more
 * Contribution License Agreements.
 *
 * \copyright
 * This Source Code Form is subject to the terms of the
 * Mozilla Public License, v. 2.0. If a  copy of the MPL was not distributed with
 * this file, You can obtain one at http://mozilla.org/MPL/2.0/.
 *
 *
 * \author Christian Linke, christian.linke@bmw.de BMW 2011,2012
 *
 * \file TAmPluginTemplate.h
 * For further information see http://www.genivi.org/.
 *
 */

#ifndef PLUGINTEMPLATE_H_
#define PLUGINTEMPLATE_H_

#include <dlfcn.h>
#include <libgen.h>
#include "CAmDltWrapper.h"

namespace am
{

/**
 *  * This template tries to load a library and cast to a class
 * @param libname the full path to the library to be loaded
 * @param libraryHandle the handle to the library that gets returned
 * @return returns the pointer to the class to be loaded
 */
template<class T> T* getCreateFunction(const std::string& libname, void*& libraryHandle)
{

    logInfo("getCreateFunction : Trying to load library with name: ",libname);

    // cut off directories
    char* fileWithPath = const_cast<char*>(libname.c_str());
    std::string libFileName = basename(fileWithPath);

    // cut off "lib" in front and cut off .so end"
    std::string createFunctionName = libFileName.substr(3, libFileName.length() - 6) + "Factory";
    // open library
    dlerror(); // Clear any existing error
    libraryHandle = dlopen(libname.c_str(), RTLD_LAZY );
    const char* dlopen_error = dlerror();
    if (!libraryHandle || dlopen_error)
    {
        logError("getCreateFunction : dlopen failed",dlopen_error);
        return (0);
    }

    // get entry point from shared lib
    dlerror(); // Clear any existing error

    union
    {
        void* voidPointer;
        T* typedPointer;
    } functionPointer;

    // Note: direct cast is not allowed by ISO C++. e.g.
    // T* createFunction = reinterpret_cast<T*>(dlsym(libraryHandle, createFunctionName.c_str()));
    // compiler warning: "forbids casting between pointer-to-function and pointer-to-object"

    functionPointer.voidPointer = dlsym(libraryHandle, createFunctionName.c_str());
    T* createFunction = functionPointer.typedPointer;

    const char* dlsym_error = dlerror();
    if (!createFunction || dlsym_error)
    {
        logError("getCreateFunction: Failed to load shared lib entry point",dlsym_error);
    }
    else
    {
        logInfo("getCreateFunction : loaded successfully plugin", createFunctionName);
    }
    return (createFunction);
}

/**
 *  * This template tries to destroy
 * @param libname the full path to the library to be loaded
 *
 */
template<class T> T* getDestroyFunction(const std::string& libname,void* libraryHandle)
{
    logInfo("destroy : Trying to destroy : ",libname);

    // cut off directories
    char* fileWithPath = const_cast<char*>(libname.c_str());
    std::string libFileName = basename(fileWithPath);

    // cut off "lib" in front and cut off .so end"
    std::string destroyFunctionName = "destroy" + libFileName.substr(3, libFileName.length() - 6);

    // get entry point from shared lib
    dlerror(); // Clear any existing error
    union
    {
        void* voidPointer;
        T* typedPointer;
    } functionPointer;

    functionPointer.voidPointer = dlsym(libraryHandle, destroyFunctionName.c_str());
    T* destroyFunction = functionPointer.typedPointer;

    const char* dlsym_error = dlerror();
    if (!destroyFunction || dlsym_error)
    {
        logError("getDestroyFunction: Failed to load shared lib entry point function name=",
                                            destroyFunctionName, "error=",dlsym_error);
    }
    else
    {
        logInfo("getDestroyFunction: loaded successfully plugin", destroyFunctionName);
    }
    return (destroyFunction);
}

}

#endif /* PLUGINTEMPLATE_H_ */