Merge pull request #2309 from mitza-oci/warnings
[ACE_TAO.git] / ACE / tests / DLL_Test.cpp
blob72bed911a430c1902d3c82307fdba5f1a5520bc4
2 //=============================================================================
3 /**
4 * @file DLL_Test.cpp
6 * This test illustrates the use of <ACE_DLL> wrapper class.
8 * @author Kirthika Parameswaran <kirthika@cs.wustl.edu>
9 */
10 //=============================================================================
12 #include "test_config.h"
13 #include "ace/DLL.h"
14 #include <memory>
15 #include "ace/ACE.h"
16 #include "ace/DLL_Manager.h"
17 #include "ace/SString.h"
18 #include "ace/OS_NS_dlfcn.h"
19 #include "DLL_Test.h"
21 #include <memory>
23 #if defined (ACE_LD_DECORATOR_STR)
24 # define OBJ_SUFFIX ACE_LD_DECORATOR_STR ACE_DLL_SUFFIX
25 #else
26 # define OBJ_SUFFIX ACE_DLL_SUFFIX
27 #endif /* ACE_LD_DECORATOR_STR */
29 #if defined (ACE_WIN32)
30 # define OBJ_PREFIX ACE_DLL_PREFIX
31 #else
32 # define OBJ_PREFIX ACE_TEXT("./") ACE_DLL_PREFIX
33 #endif /* ACE_WIN32 */
35 // Declare the type of the symbol:
36 using Hello_Factory = Hello *(*)();
37 using PFN = int (*)(Parent *);
39 int handle_test (ACE_DLL &dll)
41 // Test the get/set_handle methods.
42 ACE_DLL local_dll;
44 ACE_SHLIB_HANDLE handle = dll.get_handle (1);
45 if (handle != ACE_SHLIB_INVALID_HANDLE)
47 if (local_dll.set_handle (handle) != 0)
48 ACE_ERROR_RETURN ((LM_ERROR,
49 ACE_TEXT ("Error setting handle.\n")),
50 -1);
51 return 0;
53 ACE_ERROR_RETURN ((LM_ERROR,
54 ACE_TEXT ("Error getting handle.\n")),
55 -1);
58 int basic_test (ACE_DLL &dll)
60 ACE_TString dll_file;
61 const char *subdir_env = ACE_OS::getenv ("ACE_EXE_SUB_DIR");
62 if (subdir_env)
64 dll_file = ACE_TEXT_CHAR_TO_TCHAR (subdir_env);
65 dll_file += ACE_DIRECTORY_SEPARATOR_STR;
68 dll_file += OBJ_PREFIX ACE_TEXT ("DLL_Test_Lib") OBJ_SUFFIX;
70 int retval = dll.open (dll_file.c_str());
72 if (retval != 0)
74 ACE_TCHAR *dll_error = dll.error ();
75 ACE_ERROR_RETURN ((LM_ERROR,
76 ACE_TEXT ("Error in DLL Open of <%s>: %s\n"),
77 OBJ_PREFIX ACE_TEXT ("DLL_Test_Lib") OBJ_SUFFIX,
78 dll_error ? dll_error : ACE_TEXT ("unknown error")),
79 -1);
82 // Just because the ANSI C++ spec says you can no longer cast a
83 // void* to a function pointer. Doesn't allow:
84 // TC f = (Hello_Factory) dll.symbol ("get_hello");
85 void *foo = dll.symbol (ACE_TEXT ("get_hello"));
87 // Cast the void* to long first.
88 ptrdiff_t tmp = reinterpret_cast<ptrdiff_t> (foo);
89 Hello_Factory factory = reinterpret_cast<Hello_Factory> (tmp);
90 if (factory == 0)
91 ACE_ERROR_RETURN ((LM_ERROR,
92 ACE_TEXT ("%p\n"),
93 dll.error ()),
94 -1);
96 std::unique_ptr<Hello> my_hello (factory ());
98 // Make the method calls, as the object pointer is available.
99 my_hello->say_hello ();
100 my_hello->say_next ();
102 // Allocate and delete a string allocated via new in a different dll.
103 ACE_TCHAR *new_str = my_hello->new_info ();
104 ACE_DEBUG ((LM_DEBUG, ACE_TEXT ("Result for new_info(): %s\n"), new_str));
105 ACE::strdelete (new_str);
107 // Allocate and free a string allocated via malloc in a different dll.
108 ACE_TCHAR *malloc_str = my_hello->malloc_info ();
109 ACE_DEBUG ((LM_DEBUG, ACE_TEXT ("Result for malloc_info(): %s\n"), malloc_str));
110 ACE_OS::free (malloc_str);
112 return 0;
115 int dynamic_cast_test (ACE_DLL &dll)
117 Child child;
118 child.test();
120 Parent *parent = &child;
122 void * foo = dll.symbol (ACE_TEXT ("dynamic_cast_test"));
124 // Cast the void* to long first.
125 ptrdiff_t tmp = reinterpret_cast<ptrdiff_t> (foo);
126 PFN pfnAcquire = reinterpret_cast<PFN> (tmp);
127 if (pfnAcquire == 0)
128 ACE_ERROR_RETURN ((LM_ERROR,
129 ACE_TEXT ("%p\n"),
130 dll.error ()),
131 -1);
133 ACE_DEBUG ((LM_DEBUG, ACE_TEXT ("before %@ %@\n"),
134 &child, dynamic_cast<Child*> (parent)));
136 if (pfnAcquire (&child) == -1)
137 ACE_ERROR_RETURN ((LM_ERROR, ACE_TEXT ("dynamic_cast failed.\n")), -1);
139 return 0;
143 run_main (int, ACE_TCHAR *[])
145 ACE_START_TEST (ACE_TEXT ("DLL_Test"));
147 int retval = 0;
149 // Protection against this test being run on platforms not supporting Dlls.
150 #if defined(ACE_HAS_DYNAMIC_LINKING)
152 ACE_DLL dll;
154 retval += basic_test (dll);
156 retval += dynamic_cast_test (dll);
158 retval += handle_test (dll);
160 // Call close here so that any errors make it into the log.
161 dll.close ();
163 #else
164 ACE_ERROR ((LM_INFO,
165 ACE_TEXT ("Dynamically Linkable Libraries not supported on this platform\n")));
166 #endif /* ACE_HAS_DYNAMIC_LINKING */
168 void* invalid_handle = ACE_OS::dlsym (ACE_SHLIB_INVALID_HANDLE, ACE_TEXT ("open"));
169 if (invalid_handle != nullptr)
171 ACE_ERROR ((LM_ERROR, ACE_TEXT ("ACE_OS::dlsym using invalid handle should be nullptr and not %@\n")));
172 ++retval;
174 else
176 ACE_DEBUG ((LM_DEBUG, ACE_TEXT ("dlsym on invalid handle returned nullptr\n")));
179 ACE_END_TEST;
180 return retval == 0 ? 0 : 1;