dlopen.c 2.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384
  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. #include <rtthread.h>
  11. #include <rtm.h>
  12. #include <string.h>
  13. #include "dlmodule.h"
  14. #define MODULE_ROOT_DIR "/modules"
  15. /**
  16. * @brief dynamically load a shared library at runtime.
  17. *
  18. * @param filename the path to the shared library to load, which shouldn't be set to NULL.
  19. * @param flags options for loading the shared library.
  20. * @return void* on success, it returns a handle (a pointer) to the opened shared library, otherwise it returns NULL.
  21. *
  22. * @note This function is an API of POSIX standard, which is used for dynamically loading shared libraries at runtime.
  23. * the function first tries to check if the module is already loaded, by finding module in module list.
  24. * If module is found in memory (RT_NULL check fails), the reference count (nref) is incremented.
  25. * Otherwise, dlmodule_load() will be called to load the module into memory.
  26. * A handle (a pointer to the module) is returned at last, which can be used with other functions like dlsym().
  27. */
  28. void* dlopen(const char *filename, int flags)
  29. {
  30. struct rt_dlmodule *module;
  31. char *fullpath;
  32. const char *def_path = MODULE_ROOT_DIR;
  33. char module_name[RT_NAME_MAX];
  34. /* check parameters */
  35. RT_ASSERT(filename != RT_NULL);
  36. if (filename[0] != '/') /* it's a relative path, prefix with MODULE_ROOT_DIR */
  37. {
  38. fullpath = rt_malloc(strlen(def_path) + strlen(filename) + 2);
  39. /* join path and file name */
  40. rt_snprintf(fullpath, strlen(def_path) + strlen(filename) + 2,
  41. "%s/%s", def_path, filename);
  42. }
  43. else
  44. {
  45. fullpath = (char *)filename; /* absolute path, use it directly */
  46. }
  47. /* Extract module name from path (strip directory and extension)
  48. * This matches the logic in _dlmodule_set_name() so that dlmodule_find()
  49. * can properly locate already-loaded modules by their stored name.
  50. */
  51. dlmodule_extract_name(fullpath, module_name, RT_NAME_MAX);
  52. rt_enter_critical();
  53. /* find in module list using the stripped module name */
  54. module = dlmodule_find(module_name);
  55. if (module != RT_NULL)
  56. {
  57. rt_exit_critical();
  58. module->nref++;
  59. }
  60. else
  61. {
  62. rt_exit_critical();
  63. module = dlmodule_load(fullpath);
  64. }
  65. if (fullpath != filename)
  66. {
  67. rt_free(fullpath);
  68. }
  69. return (void *)module;
  70. }
  71. RTM_EXPORT(dlopen);