2 //=============================================================================
6 * This test illustrates the use of <ACE_DLL> wrapper class.
8 * @author Kirthika Parameswaran <kirthika@cs.wustl.edu>
10 //=============================================================================
12 #include "test_config.h"
16 #include "ace/DLL_Manager.h"
17 #include "ace/SString.h"
18 #include "ace/OS_NS_dlfcn.h"
23 #if defined (ACE_LD_DECORATOR_STR)
24 # define OBJ_SUFFIX ACE_LD_DECORATOR_STR ACE_DLL_SUFFIX
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
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.
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")),
53 ACE_ERROR_RETURN ((LM_ERROR
,
54 ACE_TEXT ("Error getting handle.\n")),
58 int basic_test (ACE_DLL
&dll
)
61 const char *subdir_env
= ACE_OS::getenv ("ACE_EXE_SUB_DIR");
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());
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")),
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
);
91 ACE_ERROR_RETURN ((LM_ERROR
,
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
);
115 int dynamic_cast_test (ACE_DLL
&dll
)
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
);
128 ACE_ERROR_RETURN ((LM_ERROR
,
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);
143 run_main (int, ACE_TCHAR
*[])
145 ACE_START_TEST (ACE_TEXT ("DLL_Test"));
149 // Protection against this test being run on platforms not supporting Dlls.
150 #if defined(ACE_HAS_DYNAMIC_LINKING)
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.
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")));
176 ACE_DEBUG ((LM_DEBUG
, ACE_TEXT ("dlsym on invalid handle returned nullptr\n")));
180 return retval
== 0 ? 0 : 1;