Merge pull request #1844 from jrw972/monterey
[ACE_TAO.git] / ACE / tests / DLL_Test.cpp
blob1c1b8cda4a3593779fc328e003336a7e84d76f67
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 "ace/Auto_Ptr.h"
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) || defined (ACE_OPENVMS)
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 typedef Hello *(*Hello_Factory)(void);
38 typedef int ( *PFN )( Parent* );
40 int handle_test (ACE_DLL &dll)
42 // Test the get/set_handle methods.
43 ACE_DLL local_dll;
45 ACE_SHLIB_HANDLE handle = dll.get_handle (1);
46 if (handle != ACE_SHLIB_INVALID_HANDLE)
48 if (local_dll.set_handle (handle) != 0)
49 ACE_ERROR_RETURN ((LM_ERROR,
50 ACE_TEXT ("Error setting handle.\n")),
51 -1);
52 return 0;
54 ACE_ERROR_RETURN ((LM_ERROR,
55 ACE_TEXT ("Error getting handle.\n")),
56 -1);
59 int basic_test (ACE_DLL &dll)
62 ACE_TString dll_file;
63 const char *subdir_env = ACE_OS::getenv ("ACE_EXE_SUB_DIR");
64 if (subdir_env)
66 dll_file = ACE_TEXT_CHAR_TO_TCHAR (subdir_env);
67 dll_file += ACE_DIRECTORY_SEPARATOR_STR;
70 dll_file += OBJ_PREFIX ACE_TEXT ("DLL_Test_Lib") OBJ_SUFFIX;
72 int retval = dll.open (dll_file.c_str());
74 if (retval != 0)
76 ACE_TCHAR *dll_error = dll.error ();
77 ACE_ERROR_RETURN ((LM_ERROR,
78 ACE_TEXT ("Error in DLL Open of <%s>: %s\n"),
79 OBJ_PREFIX ACE_TEXT ("DLL_Test_Lib") OBJ_SUFFIX,
80 dll_error ? dll_error : ACE_TEXT ("unknown error")),
81 -1);
84 // Just because the ANSI C++ spec says you can no longer cast a
85 // void* to a function pointer. Doesn't allow:
86 // TC f = (Hello_Factory) dll.symbol ("get_hello");
87 void *foo = dll.symbol (ACE_TEXT ("get_hello"));
89 // Cast the void* to long first.
90 ptrdiff_t tmp = reinterpret_cast<ptrdiff_t> (foo);
91 Hello_Factory factory = reinterpret_cast<Hello_Factory> (tmp);
92 if (factory == 0)
93 ACE_ERROR_RETURN ((LM_ERROR,
94 ACE_TEXT ("%p\n"),
95 dll.error ()),
96 -1);
98 #if defined ACE_HAS_CPP11
99 std::unique_ptr<Hello> my_hello (factory ());
100 #else
101 auto_ptr<Hello> my_hello (factory ());
102 #endif
104 // Make the method calls, as the object pointer is available.
105 my_hello->say_hello ();
106 my_hello->say_next ();
108 // Allocate and delete a string allocated via new in a different dll.
109 ACE_TCHAR *new_str = my_hello->new_info ();
110 ACE_DEBUG ((LM_DEBUG, ACE_TEXT ("Result for new_info(): %s\n"), new_str));
111 ACE::strdelete (new_str);
113 // Allocate and free a string allocated via malloc in a different dll.
114 ACE_TCHAR *malloc_str = my_hello->malloc_info ();
115 ACE_DEBUG ((LM_DEBUG, ACE_TEXT ("Result for malloc_info(): %s\n"), malloc_str));
116 ACE_OS::free (malloc_str);
118 return 0;
121 int dynamic_cast_test (ACE_DLL &dll)
123 Child child;
124 child.test();
126 Parent *parent = &child;
128 void * foo = dll.symbol (ACE_TEXT ("dynamic_cast_test"));
130 // Cast the void* to long first.
131 ptrdiff_t tmp = reinterpret_cast<ptrdiff_t> (foo);
132 PFN pfnAcquire = reinterpret_cast<PFN> (tmp);
133 if (pfnAcquire == 0)
134 ACE_ERROR_RETURN ((LM_ERROR,
135 ACE_TEXT ("%p\n"),
136 dll.error ()),
137 -1);
139 ACE_DEBUG ((LM_DEBUG, ACE_TEXT ("before %@ %@\n"),
140 &child, dynamic_cast<Child*> (parent)));
142 if (pfnAcquire (&child) == -1)
143 ACE_ERROR_RETURN ((LM_ERROR, ACE_TEXT ("dynamic_cast failed.\n")), -1);
145 return 0;
150 run_main (int, ACE_TCHAR *[])
152 ACE_START_TEST (ACE_TEXT ("DLL_Test"));
154 int retval = 0;
156 // Protection against this test being run on platforms not supporting Dlls.
157 #if defined(ACE_HAS_DYNAMIC_LINKING)
159 ACE_DLL dll;
161 retval += basic_test (dll);
163 retval += dynamic_cast_test (dll);
165 retval += handle_test (dll);
167 // Call close here so that any errors make it into the log.
168 dll.close ();
170 #else
171 ACE_ERROR ((LM_INFO,
172 ACE_TEXT ("Dynamically Linkable Libraries not supported on this platform\n")));
173 #endif /* ACE_HAS_DYNAMIC_LINKING */
175 ACE_TEST_ASSERT (ACE_OS::dlsym (ACE_SHLIB_INVALID_HANDLE, ACE_TEXT ("open")));
177 ACE_END_TEST;
178 return retval == 0 ? 0 : 1;