1 /*
2 * Copyright (c) 2006-2024 RT-Thread Development Team
3 *
4 * SPDX-License-Identifier: Apache-2.0
5 *
6 * Change Logs:
7 * Date Author Notes
8 * 2010-11-17 yi.qiu first version
9 */
10
11 #include <rtthread.h>
12 #include <rtm.h>
13 #include <string.h>
14
15 #include "dlmodule.h"
16
17 #define MODULE_ROOT_DIR "/modules"
18
19 /**
20 * @brief dynamically load a shared library at runtime.
21 *
22 * @param filename the path to the shared library to load, which shouldn't be set to NULL.
23 * @param flags options for loading the shared library.
24 * @return void* on success, it returns a handle (a pointer) to the opened shared library, otherwise it returns NULL.
25 *
26 * @note This function is an API of POSIX standard, which is used for dynamically loading shared libraries at runtime.
27 * the function first tries to check if the module is already loaded, by finding module in module list.
28 * If module is found in memory (RT_NULL check fails), the reference count (nref) is incremented.
29 * Otherwise, dlmodule_load() will be called to load the module into memory.
30 * A handle (a pointer to the module) is returned at last, which can be used with other functions like dlsym().
31 */
dlopen(const char * filename,int flags)32 void* dlopen(const char *filename, int flags)
33 {
34 struct rt_dlmodule *module;
35 char *fullpath;
36 const char*def_path = MODULE_ROOT_DIR;
37
38 /* check parameters */
39 RT_ASSERT(filename != RT_NULL);
40
41 if (filename[0] != '/') /* it's a relative path, prefix with MODULE_ROOT_DIR */
42 {
43 fullpath = rt_malloc(strlen(def_path) + strlen(filename) + 2);
44
45 /* join path and file name */
46 rt_snprintf(fullpath, strlen(def_path) + strlen(filename) + 2,
47 "%s/%s", def_path, filename);
48 }
49 else
50 {
51 fullpath = (char*)filename; /* absolute path, use it directly */
52 }
53
54 rt_enter_critical();
55
56 /* find in module list */
57 module = dlmodule_find(fullpath);
58
59 if(module != RT_NULL)
60 {
61 rt_exit_critical();
62 module->nref++;
63 }
64 else
65 {
66 rt_exit_critical();
67 module = dlmodule_load(fullpath);
68 }
69
70 if(fullpath != filename)
71 {
72 rt_free(fullpath);
73 }
74
75 return (void*)module;
76 }
77 RTM_EXPORT(dlopen);
78