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"
14 #include "ace/Auto_Ptr.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) || defined (ACE_OPENVMS)
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 typedef Hello
*(*Hello_Factory
)(void);
38 typedef int ( *PFN
)( Parent
* );
40 int handle_test (ACE_DLL
&dll
)
42 // Test the get/set_handle methods.
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")),
54 ACE_ERROR_RETURN ((LM_ERROR
,
55 ACE_TEXT ("Error getting handle.\n")),
59 int basic_test (ACE_DLL
&dll
)
63 const char *subdir_env
= ACE_OS::getenv ("ACE_EXE_SUB_DIR");
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());
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")),
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
);
93 ACE_ERROR_RETURN ((LM_ERROR
,
98 #if defined ACE_HAS_CPP11
99 std::unique_ptr
<Hello
> my_hello (factory ());
101 auto_ptr
<Hello
> my_hello (factory ());
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
);
121 int dynamic_cast_test (ACE_DLL
&dll
)
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
);
134 ACE_ERROR_RETURN ((LM_ERROR
,
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);
150 run_main (int, ACE_TCHAR
*[])
152 ACE_START_TEST (ACE_TEXT ("DLL_Test"));
156 // Protection against this test being run on platforms not supporting Dlls.
157 #if defined(ACE_HAS_DYNAMIC_LINKING)
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.
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")));
178 return retval
== 0 ? 0 : 1;