Dynamic library loading functions were added to ddsrt

ddsrt_dlopen ddsrt_dlclose ddsrt_dlsym and ddsrt_dlerror functions can be used
in posix and windows platforms that support dynamic loading

Signed-off-by: Kurtulus Oksuztepe <kurtulus.oksuztepe@adlinktech.com>
This commit is contained in:
Kurtulus Oksuztepe 2019-07-01 16:33:24 +02:00 committed by eboasson
parent 98cf8e2ae5
commit a65d3db7c8
9 changed files with 633 additions and 3 deletions

View file

@ -18,8 +18,13 @@ if(DEFINED ENV{M2_HOME})
endif()
# Chocolatey installs packages under C:\ProgramData\chocolatey.
if(ENV{ProgramData} AND IS_DIRECTORY "$ENV{ProgramData}/chocolatey/bin")
if(NOT "$ENV{ProgramData}" STREQUAL "")
if(IS_DIRECTORY "$ENV{ProgramData}/chocolatey/bin")
list(APPEND _mvn_paths "$ENV{ProgramData}/chocolatey/bin")
endif()
if(IS_DIRECTORY "$ENV{ProgramData}/chocolatey/bin")
list(APPEND _dirs "$ENV{ProgramData}/chocolatey/lib/maven")
endif()
endif()
# Maven documentation mentions intalling maven under C:\Program Files on

View file

@ -66,6 +66,7 @@ list(APPEND headers
"${include_path}/dds/ddsrt/misc.h"
"${include_path}/dds/ddsrt/io.h"
"${include_path}/dds/ddsrt/process.h"
"${include_path}/dds/ddsrt/dynlib.h"
"${include_path}/dds/ddsrt/strtod.h"
"${include_path}/dds/ddsrt/strtol.h"
"${include_path}/dds/ddsrt/types.h")
@ -102,7 +103,7 @@ list(APPEND sources
# network stack. In order to mix-and-match various compilers, architectures,
# operating systems, etc input from the build system is required.
foreach(feature atomics cdtors environ heap ifaddrs random rusage
sockets string sync threads time md5 process)
sockets string sync threads time md5 process dynlib)
if(EXISTS "${include_path}/dds/ddsrt/${feature}.h")
list(APPEND headers "${include_path}/dds/ddsrt/${feature}.h")
file(GLOB
@ -176,6 +177,7 @@ target_sources(ddsrt INTERFACE ${sources})
set(CMAKE_THREAD_PREFER_PTHREAD TRUE)
find_package(Threads REQUIRED)
target_link_libraries(ddsrt INTERFACE Threads::Threads)
target_link_libraries(ddsrt INTERFACE ${CMAKE_DL_LIBS})
if(WIN32)
target_link_libraries(ddsrt INTERFACE wsock32 ws2_32 iphlpapi bcrypt)

View file

@ -0,0 +1,143 @@
/*
* Copyright(c) 2006 to 2018 ADLINK Technology Limited and others
*
* This program and the accompanying materials are made available under the
* terms of the Eclipse Public License v. 2.0 which is available at
* http://www.eclipse.org/legal/epl-2.0, or the Eclipse Distribution License
* v. 1.0 which is available at
* http://www.eclipse.org/org/documents/edl-v10.php.
*
* SPDX-License-Identifier: EPL-2.0 OR BSD-3-Clause
*/
#ifndef DDSRT_LIBRARY_H
#define DDSRT_LIBRARY_H
#include "dds/export.h"
#include "dds/ddsrt/types.h"
#include "dds/ddsrt/retcode.h"
#include "dds/ddsrt/attributes.h"
#if defined (__cplusplus)
extern "C" {
#endif
//typedef void *ddsrt_dynlib_t;
typedef struct ddsrt_dynlib *ddsrt_dynlib_t;
/**
* @brief Load a dynamic shared library.
*
* The function ddsrt_dlopen() loads the dynamic shared object (shared library)
* file, identified by 'name', sets the handle parameter for the loaded library and
* returns the result with dds return code.
*
* If the 'translate' boolean is true, this function will first try to open the
* library with a translated 'name'. Translated in this context means that if
* "mylibrary" is provided, it will be translated into libmylibrary.so,
* libmylibrary.dylib or mylibrary.dll depending on the platform.
* This translation only happens when the given name does not contain
* a directory.
* If the function isn't able to load the library with the translated name, it
* will still try the given name.
*
* @param[in] name Library file name.
* @param[in] translate Automatic name translation on/off.
* @param[out] handle Library handle that will be assigned after successfull operation. It is assigned to NULL if loading fails.
*
* @returns A dds_retcode_t indicating success or failure.
*
* @retval DDS_RETCODE_OK
* Library handle was successfully loaded.
* @retval DDS_RETCODE_BAD_PARAM
* There is an invalid input in the parameter list
* @retval DDS_RETCODE_ERROR
* Loading failed.
* Use ddsrt_dlerror() to diagnose the failure.
*/
DDS_EXPORT dds_retcode_t
ddsrt_dlopen(
const char *name,
bool translate,
ddsrt_dynlib_t *handle) ddsrt_nonnull_all;
/**
* @brief Close the library.
*
* The function ddsrt_dlclose() informs the system that the
* library, identified by 'handle', is no longer needed.
* will get the memory address of a symbol,
* identified by 'symbol', from a loaded library 'handle'.
*
* @param[in] handle Library handle.
*
* @returns A dds_retcode_t indicating success or failure.
*
* @retval DDS_RETCODE_OK
* Library handle was successfully closed.
* @retval DDS_RETCODE_ERROR
* Library closing failed.
* Use ddsrt_dlerror() to diagnose the failure.
*/
DDS_EXPORT dds_retcode_t
ddsrt_dlclose(
ddsrt_dynlib_t handle);
/**
* @brief Get the memory address of a symbol.
*
* The function ddsrt_dlsym() will get the memory address of a symbol,
* identified by 'symbol', from a loaded library 'handle'.
*
* @param[in] handle Library handle.
* @param[in] symbol Symbol name.
* @param[out] address The memory address of the loaded symbol (void*).
*
* @returns A dds_retcode_t indicating success or failure.
*
* @retval DDS_RETCODE_OK
* Symbol was found in the loaded library.
* Address parameter is ready to use.
* @retval DDS_RETCODE_ERROR
* Symbol was not found.
* Use ddsrt_dlerror() to diagnose the failure.
*/
DDS_EXPORT dds_retcode_t
ddsrt_dlsym(
ddsrt_dynlib_t handle,
const char *symbol,
void **address);
/**
* @brief Get the most recent library related error.
*
* The function ddsrt_dlerror() will return the most recent error of the operating system
* in human readable form.
*
* If no error was found, it's either due to the fact that there
* actually was no error since init or last ddsrt_dlerror() call,
* or due to an unknown unrelated error.
*
* As error reporting function can be used for different purposes, dssrt_dlerror
* function should be called immediately after calling ddsrt_dlopen or ddsrt_dlsym
* function.
*
* @returns A dds_retcode_t indicating success or failure.
*
* @retval DDS_RETCODE_OK
* Most recent library related error returned.
* @retval DDS_RETCODE_NOT_FOUND
* No library related error found.
*/
DDS_EXPORT dds_retcode_t
ddsrt_dlerror(
char *buf,
size_t buflen);
#if defined (__cplusplus)
}
#endif
#endif /* DDSRT_LIBRARY_H */

View file

@ -0,0 +1,95 @@
/*
* Copyright(c) 2006 to 2018 ADLINK Technology Limited and others
*
* This program and the accompanying materials are made available under the
* terms of the Eclipse Public License v. 2.0 which is available at
* http://www.eclipse.org/legal/epl-2.0, or the Eclipse Distribution License
* v. 1.0 which is available at
* http://www.eclipse.org/org/documents/edl-v10.php.
*
* SPDX-License-Identifier: EPL-2.0 OR BSD-3-Clause
*/
#include <stdio.h>
#include <dlfcn.h>
#include <assert.h>
#include <string.h>
#include <dds/ddsrt/dynlib.h>
#include "dds/ddsrt/heap.h"
#include "dds/ddsrt/io.h"
dds_retcode_t ddsrt_dlopen(const char *name, bool translate,
ddsrt_dynlib_t *handle) {
dds_retcode_t retcode = DDS_RETCODE_OK;
assert( handle );
*handle = NULL;
if ((translate) && (strrchr(name, '/') == NULL )) {
/* Add lib and suffix to the name and try to open. */
#if __APPLE__
static const char suffix[] = ".dylib";
#else
static const char suffix[] = ".so";
#endif
char* libName;
ddsrt_asprintf( &libName, "lib%s%s", name, suffix);
*handle = dlopen(libName, RTLD_GLOBAL | RTLD_NOW);
ddsrt_free(libName);
}
if (*handle == NULL ) {
/* name contains a path,
* (auto)translate is disabled or
* dlopen on translated name failed. */
*handle = dlopen(name, RTLD_GLOBAL | RTLD_NOW);
}
if (*handle != NULL) {
retcode = DDS_RETCODE_OK;
} else {
retcode = DDS_RETCODE_ERROR;
}
return retcode;
}
dds_retcode_t ddsrt_dlclose(ddsrt_dynlib_t handle) {
assert ( handle );
return (dlclose(handle) == 0) ? DDS_RETCODE_OK : DDS_RETCODE_ERROR;
}
dds_retcode_t ddsrt_dlsym(ddsrt_dynlib_t handle, const char *symbol,
void **address) {
dds_retcode_t retcode = DDS_RETCODE_OK;
assert( handle );
assert( address );
assert( symbol );
*address = dlsym(handle, symbol);
if (*address == NULL) {
retcode = DDS_RETCODE_ERROR;
}
return retcode;
}
dds_retcode_t ddsrt_dlerror(char *buf, size_t buflen) {
const char *err;
dds_retcode_t retcode = DDS_RETCODE_OK;
assert (buf );
err = dlerror();
if (err == NULL) {
retcode = DDS_RETCODE_NOT_FOUND;
} else {
snprintf(buf, buflen, "%s", err);
}
return retcode;
}

View file

@ -0,0 +1,95 @@
/*
* Copyright(c) 2006 to 2018 ADLINK Technology Limited and others
*
* This program and the accompanying materials are made available under the
* terms of the Eclipse Public License v. 2.0 which is available at
* http://www.eclipse.org/legal/epl-2.0, or the Eclipse Distribution License
* v. 1.0 which is available at
* http://www.eclipse.org/org/documents/edl-v10.php.
*
* SPDX-License-Identifier: EPL-2.0 OR BSD-3-Clause
*/
#include <stdio.h>
#include <assert.h>
#include <dds/ddsrt/dynlib.h>
#include <string.h>
#include "dds/ddsrt/heap.h"
#include "dds/ddsrt/types.h"
#include "dds/ddsrt/string.h"
dds_retcode_t ddsrt_dlopen(const char *name, bool translate,
ddsrt_dynlib_t *handle) {
dds_retcode_t retcode = DDS_RETCODE_OK;
assert( handle );
*handle = NULL;
if ((translate) && (strrchr(name, '/') == NULL )
&& (strrchr(name, '\\') == NULL )) {
/* Add suffix to the name and try to open. */
static const char suffix[] = ".dll";
size_t len = strlen(name) + sizeof(suffix);
char* libName = ddsrt_malloc(len);
sprintf_s(libName, len, "%s%s", name, suffix);
*handle = LoadLibrary(libName);
ddsrt_free(libName);
}
if (*handle == NULL) {
/* Name contains a path,
* (auto)translate is disabled or
* LoadLibrary on translated name failed. */
*handle = LoadLibrary(name);
}
if (*handle != NULL) {
retcode = DDS_RETCODE_OK;
} else {
retcode = DDS_RETCODE_ERROR;
}
return retcode;
}
dds_retcode_t ddsrt_dlclose(ddsrt_dynlib_t handle) {
assert ( handle );
return (FreeLibrary(handle) == 0) ? DDS_RETCODE_ERROR : DDS_RETCODE_OK;
}
dds_retcode_t ddsrt_dlsym(ddsrt_dynlib_t handle, const char *symbol,
void **address) {
dds_retcode_t retcode = DDS_RETCODE_OK;
assert( handle );
assert( address );
assert( symbol );
*address = GetProcAddress(handle, symbol);
if ( *address == NULL ) {
retcode = DDS_RETCODE_ERROR;
}
return retcode;
}
dds_retcode_t ddsrt_dlerror(char *buf, size_t buflen) {
/* Hopefully (and likely), the last error is
* related to a Library action attempt. */
DWORD err;
assert ( buf );
dds_retcode_t retcode = DDS_RETCODE_OK;
err = GetLastError();
if ( err == 0 ) {
retcode = DDS_RETCODE_NOT_FOUND;
} else {
retcode = ddsrt_strerror_r(err, buf, buflen);
}
return retcode;
}

View file

@ -10,9 +10,11 @@
# SPDX-License-Identifier: EPL-2.0 OR BSD-3-Clause
#
include(CUnit)
include(GenerateExportHeader)
set(sources
"atomics.c"
"dynlib.c"
"environ.c"
"heap.c"
"ifaddrs.c"
@ -66,3 +68,47 @@ set(process_app_name "${CMAKE_CURRENT_BINARY_DIR}/process_app${CMAKE_EXECUTABLE_
configure_file(
"process_test.h.in" "${CMAKE_CURRENT_BINARY_DIR}/include/process_test.h" @ONLY)
# Create a separate shared library that will be used to
# test dynamic library loading.
set(test_lib_name "dltestlib")
add_library(${test_lib_name} SHARED dllib.c)
# Force the lib to be at the same location, no matter what platform or build type.
set_target_properties(
${test_lib_name}
PROPERTIES
RUNTIME_OUTPUT_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR}
RUNTIME_OUTPUT_DIRECTORY_DEBUG ${CMAKE_CURRENT_BINARY_DIR}
RUNTIME_OUTPUT_DIRECTORY_RELEASE ${CMAKE_CURRENT_BINARY_DIR}
RUNTIME_OUTPUT_DIRECTORY_RELWITHDEBINFO ${CMAKE_CURRENT_BINARY_DIR}
RUNTIME_OUTPUT_DIRECTORY_MINSIZEREL ${CMAKE_CURRENT_BINARY_DIR}
LIBRARY_OUTPUT_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR}
LIBRARY_OUTPUT_DIRECTORY_DEBUG ${CMAKE_CURRENT_BINARY_DIR}
LIBRARY_OUTPUT_DIRECTORY_RELEASE ${CMAKE_CURRENT_BINARY_DIR}
LIBRARY_OUTPUT_DIRECTORY_RELWITHDEBINFO ${CMAKE_CURRENT_BINARY_DIR}
LIBRARY_OUTPUT_DIRECTORY_MINSIZEREL ${CMAKE_CURRENT_BINARY_DIR} )
# Use proper export for this test lib.
generate_export_header(${test_lib_name} BASE_NAME LIB_TEST)
target_include_directories(${test_lib_name} PRIVATE "${CMAKE_CURRENT_BINARY_DIR}")
# Let the cunit application know the location and name of the library.
file(TO_NATIVE_PATH "${CMAKE_CURRENT_BINARY_DIR}" test_lib_native_dir)
file(TO_NATIVE_PATH "/" test_lib_sep)
string(REPLACE "\\" "\\\\" test_lib_dir ${test_lib_native_dir})
string(REPLACE "\\" "\\\\" test_lib_sep ${test_lib_sep})
configure_file("dl_test.h.in" "${CMAKE_CURRENT_BINARY_DIR}/include/dl_test.h" @ONLY)
# Let ctest set the proper library path when executing library tests.
unset(test_lib_tests)
process_cunit_source_file("dynlib.c" test_lib_header test_lib_suites test_lib_tests)
foreach(libtest ${test_lib_tests})
string(REPLACE ":" ";" libtest ${libtest})
list(GET libtest 0 suite)
list(GET libtest 1 test)
set(libtestname "CUnit_${suite}_${test}")
if("${CMAKE_HOST_SYSTEM}" MATCHES ".*Windows.*")
set_property(TEST ${libtestname} APPEND PROPERTY ENVIRONMENT "${test_lib_native_dir}")
else()
set_property(TEST ${libtestname} APPEND PROPERTY ENVIRONMENT "LD_LIBRARY_PATH=${test_lib_native_dir};$ENV{LD_LIBRARY_PATH}")
endif()
endforeach()

View file

@ -0,0 +1,22 @@
/*
* Copyright(c) 2006 to 2018 ADLINK Technology Limited and others
*
* This program and the accompanying materials are made available under the
* terms of the Eclipse Public License v. 2.0 which is available at
* http://www.eclipse.org/legal/epl-2.0, or the Eclipse Distribution License
* v. 1.0 which is available at
* http://www.eclipse.org/org/documents/edl-v10.php.
*
* SPDX-License-Identifier: EPL-2.0 OR BSD-3-Clause
*/
#ifndef DDSRT_TEST_DL_TEST_H
#define DDSRT_TEST_DL_TEST_H
/* Get the library name information from cmake. */
#define TEST_LIB_NAME "@test_lib_name@"
#define TEST_LIB_DIR "@test_lib_dir@"
#define TEST_LIB_SEP "@test_lib_sep@"
#define TEST_LIB_SUFFIX "@CMAKE_SHARED_LIBRARY_SUFFIX@"
#define TEST_LIB_PREFIX "@CMAKE_SHARED_LIBRARY_PREFIX@"
#endif /* DDSRT_TEST_DL_TEST_H */

25
src/ddsrt/tests/dllib.c Normal file
View file

@ -0,0 +1,25 @@
/*
* Copyright(c) 2019 ADLINK Technology Limited and others
*
* This program and the accompanying materials are made available under the
* terms of the Eclipse Public License v. 2.0 which is available at
* http://www.eclipse.org/legal/epl-2.0, or the Eclipse Distribution License
* v. 1.0 which is available at
* http://www.eclipse.org/org/documents/edl-v10.php.
*
* SPDX-License-Identifier: EPL-2.0 OR BSD-3-Clause
*/
#include "lib_test_export.h"
static int g_val = -1;
LIB_TEST_EXPORT void set_int(int val)
{
g_val = val;
}
LIB_TEST_EXPORT int get_int(void)
{
return g_val;
}

197
src/ddsrt/tests/dynlib.c Normal file
View file

@ -0,0 +1,197 @@
/*
* Copyright(c) 2019 ADLINK Technology Limited and others
*
* This program and the accompanying materials are made available under the
* terms of the Eclipse Public License v. 2.0 which is available at
* http://www.eclipse.org/legal/epl-2.0, or the Eclipse Distribution License
* v. 1.0 which is available at
* http://www.eclipse.org/org/documents/edl-v10.php.
*
* SPDX-License-Identifier: EPL-2.0 OR BSD-3-Clause
*/
#include <stdio.h>
#include <string.h>
#include <assert.h>
#include <dds/ddsrt/dynlib.h>
#include "CUnit/Test.h"
#include "dds/ddsrt/heap.h"
#include "dds/ddsrt/string.h"
#include "dds/ddsrt/environ.h"
#include "dl_test.h"
#define TEST_LIB_FILE ""TEST_LIB_PREFIX""TEST_LIB_NAME""TEST_LIB_SUFFIX""
#define TEST_LIB_ABSOLUTE ""TEST_LIB_DIR""TEST_LIB_SEP""TEST_LIB_FILE""
#define TEST_ABORT_IF_NULL(var, msg) \
do { \
if (var == NULL) { \
char buffer[256]; \
r = ddsrt_dlerror(buffer, sizeof(buffer)); \
CU_ASSERT_EQUAL_FATAL(r, DDS_RETCODE_OK); \
printf("\n%s", buffer); \
CU_FAIL_FATAL(msg); \
} \
} while(0)
/*
* Load a library.
*/
CU_Test(ddsrt_library, dlopen_path)
{
dds_retcode_t r;
ddsrt_dynlib_t l;
printf("Absolute lib: %s\n", TEST_LIB_ABSOLUTE);
r = ddsrt_dlopen(TEST_LIB_ABSOLUTE, false, &l);
CU_ASSERT_EQUAL(r, DDS_RETCODE_OK);
CU_ASSERT_PTR_NOT_NULL(l);
TEST_ABORT_IF_NULL(l, "ddsrt_dlopen() failed. Is the proper library path set?");
r = ddsrt_dlclose(l);
CU_ASSERT_EQUAL(r, DDS_RETCODE_OK);
}
CU_Test(ddsrt_library, dlopen_file)
{
dds_retcode_t r;
ddsrt_dynlib_t l;
r = ddsrt_dlopen(TEST_LIB_FILE, false, &l);
CU_ASSERT_EQUAL(r, DDS_RETCODE_OK);
CU_ASSERT_PTR_NOT_NULL(l);
TEST_ABORT_IF_NULL(l, "ddsrt_dlopen() failed. Is the proper library path set?");
r = ddsrt_dlclose(l);
CU_ASSERT_EQUAL(r, DDS_RETCODE_OK);
}
CU_Test(ddsrt_library, dlopen_name)
{
dds_retcode_t r;
ddsrt_dynlib_t l;
r = ddsrt_dlopen(TEST_LIB_NAME, true, &l);
CU_ASSERT_EQUAL(r, DDS_RETCODE_OK);
CU_ASSERT_PTR_NOT_NULL(l);
TEST_ABORT_IF_NULL(l, "ddsrt_dlopen() failed. Is the proper library path set?");
r = ddsrt_dlclose(l);
CU_ASSERT_EQUAL(r, DDS_RETCODE_OK);
}
CU_Test(ddsrt_library, dlopen_unknown)
{
char buffer[256];
dds_retcode_t r;
ddsrt_dynlib_t l;
r = ddsrt_dlopen("UnknownLib", false, &l);
CU_ASSERT_PTR_NULL_FATAL(l);
r = ddsrt_dlerror(buffer, sizeof(buffer));
CU_ASSERT_EQUAL_FATAL(r, DDS_RETCODE_OK);
printf("\n%s", buffer);
}
CU_Test(ddsrt_library, dlsym)
{
dds_retcode_t r;
ddsrt_dynlib_t l;
void* f;
r = ddsrt_dlopen(TEST_LIB_NAME, true, &l);
CU_ASSERT_PTR_NOT_NULL(l);
CU_ASSERT_EQUAL(r, DDS_RETCODE_OK);
TEST_ABORT_IF_NULL(l, "ddsrt_dlopen() failed. Is the proper library path set?");
r = ddsrt_dlsym(l, "get_int", &f);
CU_ASSERT_EQUAL(r, DDS_RETCODE_OK);
CU_ASSERT_PTR_NOT_NULL(f);
TEST_ABORT_IF_NULL(f, "ddsrt_dlsym(l, \"get_int\") failed.");
r = ddsrt_dlclose(l);
CU_ASSERT_EQUAL(r, DDS_RETCODE_OK);
}
CU_Test(ddsrt_library, dlsym_unknown)
{
char buffer[256];
dds_retcode_t r;
ddsrt_dynlib_t l;
void* f;
r = ddsrt_dlopen(TEST_LIB_NAME, true, &l);
CU_ASSERT_PTR_NOT_NULL(l);
TEST_ABORT_IF_NULL(l,"ddsrt_dlopen() failed. Is the proper library path set?");
r = ddsrt_dlsym(l, "UnknownSym", &f);
CU_ASSERT_EQUAL(r, DDS_RETCODE_ERROR);
CU_ASSERT_PTR_NULL_FATAL(f);
r = ddsrt_dlerror(buffer, sizeof(buffer));
CU_ASSERT_EQUAL_FATAL(r, DDS_RETCODE_OK);
printf("\n%s", buffer);
r = ddsrt_dlclose(l);
CU_ASSERT_EQUAL(r, DDS_RETCODE_OK);
}
typedef void (*func_set_int)(int val);
typedef int (*func_get_int)(void);
CU_Test(ddsrt_library, call)
{
int get_int = 0;
int set_int = 1234;
func_get_int f_get;
func_set_int f_set;
dds_retcode_t r;
ddsrt_dynlib_t l;
r = ddsrt_dlopen(TEST_LIB_NAME, true, &l);
CU_ASSERT_PTR_NOT_NULL(l);
TEST_ABORT_IF_NULL(l, "ddsrt_dlopen() failed. Is the proper library path set?");
r = ddsrt_dlsym(l, "get_int", (void **)&f_get);
CU_ASSERT_PTR_NOT_NULL(f_get);
TEST_ABORT_IF_NULL(f_get, "ddsrt_dlsym(l, \"get_int\") failed.");
r = ddsrt_dlsym(l, "set_int", (void **)&f_set);
CU_ASSERT_PTR_NOT_NULL(f_set);
TEST_ABORT_IF_NULL(f_set, "ddsrt_dlsym(l, \"set_int\") failed.");
f_set(set_int);
get_int = f_get();
CU_ASSERT_EQUAL(set_int, get_int);
r = ddsrt_dlclose(l);
CU_ASSERT_EQUAL(r, DDS_RETCODE_OK);
}
CU_Test(ddsrt_library, dlclose_error)
{
dds_retcode_t r;
ddsrt_dynlib_t l;
r = ddsrt_dlopen(TEST_LIB_NAME, true, &l);
CU_ASSERT_PTR_NOT_NULL(l);
TEST_ABORT_IF_NULL(l, "ddsrt_dlopen() failed. Is the proper library path set?");
r = ddsrt_dlclose(l);
CU_ASSERT_EQUAL(r, DDS_RETCODE_OK);
r = ddsrt_dlclose( l ); /*already closed handle */
CU_ASSERT_EQUAL(r, DDS_RETCODE_ERROR);
}
CU_Test(ddsrt_library, dlerror_notfound)
{
char buffer[256];
dds_retcode_t r;
ddsrt_dlerror(buffer, sizeof(buffer));
r = ddsrt_dlerror(buffer, sizeof(buffer));
CU_ASSERT_EQUAL(r, DDS_RETCODE_NOT_FOUND);
}