Skip to content

Commit

Permalink
Merge pull request #153 from rdkcentral/feature/gh152-weak-strong-sym…
Browse files Browse the repository at this point in the history
…bols-dlopen

gh #152 : Adding a demo directory to demo usage of weak, strong and dlopen
  • Loading branch information
kanjoe24 authored Dec 19, 2024
2 parents 38990a0 + f339bfb commit 86416dd
Show file tree
Hide file tree
Showing 13 changed files with 814 additions and 0 deletions.
50 changes: 50 additions & 0 deletions tests/demo/demo_dlopen_based/Makefile
Original file line number Diff line number Diff line change
@@ -0,0 +1,50 @@
# *
# * If not stated otherwise in this file or this component's LICENSE file the
# * following copyright and licenses apply:
# *
# * Copyright 2023 RDK Management
# *
# * Licensed under the Apache License, Version 2.0 (the "License");
# * you may not use this file except in compliance with the License.
# * You may obtain a copy of the License at
# *
# * http://www.apache.org/licenses/LICENSE-2.0
# *
# * Unless required by applicable law or agreed to in writing, software
# * distributed under the License is distributed on an "AS IS" BASIS,
# * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# * See the License for the specific language governing permissions and
# * limitations under the License.
# *

# Makefile for demonstrating weak vs strong symbols using dlopen

ifeq ($(TARGET),)
CC = gcc
else
#CC = rm-rdk-linux-gnueabi-gcc -mthumb -mfpu=vfp -mcpu=cortex-a9 -mfloat-abi=soft -mabi=aapcs-linux -mno-thumb-interwork -ffixed-r8 -fomit-frame-pointer
endif
CFLAGS = -Wall -fPIC
LDFLAGS = -ldl

# Targets
EXECUTABLE = main
SHARED_LIB = libplugin.so

# Source files
MAIN_SRC = main.c
PLUGIN_SRC = plugin.c

.PHONY: all clean

all: $(EXECUTABLE) $(SHARED_LIB)

$(EXECUTABLE): $(MAIN_SRC)
$(CC) $(CFLAGS) -o $@ $^ $(LDFLAGS)

$(SHARED_LIB): $(PLUGIN_SRC)
$(CC) $(CFLAGS) -shared -o $@ $^

clean:
rm -f $(EXECUTABLE) $(SHARED_LIB)

83 changes: 83 additions & 0 deletions tests/demo/demo_dlopen_based/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,83 @@
# Plugin Loader Project using dlopen

## Overview
This project demonstrates how to create a simple C program that dynamically loads a shared library (plugin) and executes its functions. The project consists of :
- a main program (`main.c`) that loads the plugin at runtime
- and interacts with it through an interface defined in `plugin.h`.
- The plugin itself is implemented in `plugin.c`.

## Prerequisites

To build and run this project, you need:

- A C compiler (e.g., `gcc`)
- The `dl` library for dynamic linking (commonly available on Linux)
- GNU `make`

## Compilation Instructions

1. Build the project for the native architecture:
```bash
make
```

2. Build the project for an ARM target:
```bash
make TARGET=arm
```
Ensure you have the appropriate cross-compiler toolchain configured for ARM in the `Makefile`.

3. Clean up the generated files:
```bash
make clean
```

## Usage

The program dynamically loads the shared library and attempts to use the strong implementations. If a strong implementation is not found, the weak implementation is used instead.

1. Example Output for linux
```bash
./main
Plugin initialized.
Plugin action performed.
Plugin cleaned up.
```

2. Example Output for arm
```bash
root@xione-uk:/opt/jyo# ./main
Plugin initialized.
Plugin action performed.
Plugin cleaned up.
```

3. Example when plugin not found:
```bash
Plugin not found. Running without plugin.
```

## Project Details

**main.c:**

This file contains the main program that dynamically loads the libplugin.so shared library and uses the PluginInterface to call the plugin’s functions.

**plugin.c:**

This file defines the implementation of the functions specified in the PluginInterface. The functions include plugin_initialize(), plugin_perform_action(), and plugin_cleanup().

**plugin.h:**

The header file that defines the PluginInterface structure, which declares the function pointers used by the plugin.


## Dependencies

- GCC for compilation.
- `libdl` (part of the standard library) for dynamic linking.

## Notes

- Ensure the shared library (`libplugin.so`) is located in the same directory as the `main` executable, or adjust the `LD_LIBRARY_PATH` environment variable to include its location.
- This example is designed for educational purposes and demonstrates basic concepts of dynamic linking and symbol resolution in C.
73 changes: 73 additions & 0 deletions tests/demo/demo_dlopen_based/main.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,73 @@
/*
* If not stated otherwise in this file or this component's LICENSE file the
* following copyright and licenses apply:
*
* Copyright 2023 RDK Management
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/

/**
* @file main.c
* @brief Demonstrates the usage of weak symbols and dynamic loading with `dlopen` and `dlsym`.
*
* This program attempts to load strong implementations of functions from a shared library.
* If a strong implementation is not found, the weak implementations in this file are used.
*/

/**
* @file main.c
* @brief Main program to demonstrate dynamic loading of a plugin.
*
* This program attempts to dynamically load a shared library plugin and
* execute its functions if available. If the plugin is not found, it runs without the plugin.
*/

#include <stdio.h>
#include <dlfcn.h>
#include "plugin.h"

/**
* @brief Entry point for the program.
*
* Attempts to dynamically load a plugin shared library and execute its
* interface functions (`initialize`, `perform_action`, `cleanup`). If the
* plugin is unavailable, the program proceeds without it.
*
* @returns 0 on successful execution.
*/
int main(void)
{
void *handle; /**< Handle for the dynamically loaded shared library. */
PluginInterface *plugin = NULL; /**< Pointer to the plugin interface. */

// Attempt to load the plugin dynamically
handle = dlopen("./libplugin.so", RTLD_LAZY);
if (handle)
{
plugin = (PluginInterface *)dlsym(handle, "plugin");
if (plugin)
{
plugin->initialize();
plugin->perform_action();
plugin->cleanup();
}
dlclose(handle);
}
else
{
printf("Plugin not found. Running without plugin.\n");
}

return 0;
}
70 changes: 70 additions & 0 deletions tests/demo/demo_dlopen_based/plugin.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,70 @@
/*
* If not stated otherwise in this file or this component's LICENSE file the
* following copyright and licenses apply:
*
* Copyright 2023 RDK Management
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/

/**
* @file plugin.c
* @brief Implementation of the plugin interface.
*
* This file defines the functions that form the plugin's interface,
* including initialization, performing an action, and cleanup.
*/

#include "plugin.h"
#include <stdio.h>

/**
* @brief Initializes the plugin.
*
* This function performs any necessary setup for the plugin.
*/
void plugin_initialize(void)
{
printf("Plugin initialized.\n");
}

/**
* @brief Executes the main action of the plugin.
*
* This function is called to perform the core functionality of the plugin.
*/
void plugin_perform_action(void)
{
printf("Plugin action performed.\n");
}

/**
* @brief Cleans up the plugin.
*
* This function performs any necessary cleanup before the plugin is unloaded.
*/
void plugin_cleanup(void)
{
printf("Plugin cleaned up.\n");
}

/**
* @brief Global instance of the plugin interface.
*
* This structure defines the plugin's interface, mapping its functions to the
* corresponding implementation.
*/
PluginInterface plugin = {
.initialize = plugin_initialize,
.perform_action = plugin_perform_action,
.cleanup = plugin_cleanup};
66 changes: 66 additions & 0 deletions tests/demo/demo_dlopen_based/plugin.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,66 @@
/*
* If not stated otherwise in this file or this component's LICENSE file the
* following copyright and licenses apply:
*
* Copyright 2023 RDK Management
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/

/**
* @file plugin.h
* @brief Defines the interface for the plugin.
*
* This header file declares the `PluginInterface` structure, which contains
* function pointers representing the plugin's operations: initialization,
* performing an action, and cleanup.
*/

#ifndef PLUGIN_H
#define PLUGIN_H

/**
* @brief Structure representing the plugin interface.
*
* This structure contains pointers to functions that define the behavior
* of a plugin. These functions are expected to be implemented by any plugin
* conforming to this interface.
*/
typedef struct
{
/**
* @brief Initializes the plugin.
*
* This function pointer should point to a function that sets up the plugin
* before it is used.
*/
void (*initialize)(void);

/**
* @brief Performs the primary action of the plugin.
*
* This function pointer should point to a function that executes the main
* functionality of the plugin.
*/
void (*perform_action)(void);

/**
* @brief Cleans up the plugin.
*
* This function pointer should point to a function that releases any
* resources or performs finalization tasks for the plugin.
*/
void (*cleanup)(void);
} PluginInterface;

#endif // PLUGIN_H
Loading

0 comments on commit 86416dd

Please sign in to comment.