1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177
|
//=============================================================================
/**
* @file DLL_Test.cpp
*
* $Id: DLL_Test.cpp 93638 2011-03-24 13:16:05Z johnnyw $
*
* This test illustrates the use of <ACE_DLL> wrapper class.
*
*
* @author Kirthika Parameswaran <kirthika@cs.wustl.edu>
*/
//=============================================================================
#include "test_config.h"
#include "ace/DLL.h"
#include "ace/Auto_Ptr.h"
#include "ace/ACE.h"
#include "ace/DLL_Manager.h"
#include "ace/SString.h"
#include "DLL_Test.h"
#if defined (ACE_LD_DECORATOR_STR)
# define OBJ_SUFFIX ACE_LD_DECORATOR_STR ACE_DLL_SUFFIX
#else
# define OBJ_SUFFIX ACE_DLL_SUFFIX
#endif /* ACE_LD_DECORATOR_STR */
#if defined (ACE_WIN32) || defined (ACE_OPENVMS)
# define OBJ_PREFIX ACE_DLL_PREFIX
#else
# define OBJ_PREFIX ACE_TEXT("./") ACE_DLL_PREFIX
#endif /* ACE_WIN32 */
// Declare the type of the symbol:
typedef Hello *(*Hello_Factory)(void);
typedef int ( *PFN )( Parent* );
int handle_test (ACE_DLL &dll)
{
// Test the get/set_handle methods.
ACE_DLL local_dll;
ACE_SHLIB_HANDLE handle = dll.get_handle (1);
if (handle != ACE_SHLIB_INVALID_HANDLE)
{
if (local_dll.set_handle (handle) != 0)
ACE_ERROR_RETURN ((LM_ERROR,
ACE_TEXT ("Error setting handle.\n")),
-1);
return 0;
}
ACE_ERROR_RETURN ((LM_ERROR,
ACE_TEXT ("Error getting handle.\n")),
-1);
}
int basic_test (ACE_DLL &dll)
{
ACE_TString dll_file;
const char *subdir_env = ACE_OS::getenv ("ACE_EXE_SUB_DIR");
if (subdir_env)
{
dll_file = ACE_TEXT_CHAR_TO_TCHAR (subdir_env);
dll_file += ACE_DIRECTORY_SEPARATOR_STR;
}
dll_file += OBJ_PREFIX ACE_TEXT ("DLL_Test_Lib") OBJ_SUFFIX;
int retval = dll.open (dll_file.c_str());
if (retval != 0)
{
ACE_TCHAR *dll_error = dll.error ();
ACE_ERROR_RETURN ((LM_ERROR,
ACE_TEXT ("Error in DLL Open of <%s>: %s\n"),
OBJ_PREFIX ACE_TEXT ("DLL_Test_Lib") OBJ_SUFFIX,
dll_error ? dll_error : ACE_TEXT ("unknown error")),
-1);
}
// Just because the ANSI C++ spec says you can no longer cast a
// void* to a function pointer. Doesn't allow:
// TC f = (Hello_Factory) dll.symbol ("get_hello");
void *foo = dll.symbol (ACE_TEXT ("get_hello"));
// Cast the void* to long first.
ptrdiff_t tmp = reinterpret_cast<ptrdiff_t> (foo);
Hello_Factory factory = reinterpret_cast<Hello_Factory> (tmp);
if (factory == 0)
ACE_ERROR_RETURN ((LM_ERROR,
ACE_TEXT ("%p\n"),
dll.error ()),
-1);
auto_ptr<Hello> my_hello (factory ());
// Make the method calls, as the object pointer is available.
my_hello->say_hello ();
my_hello->say_next ();
// Allocate and delete a string allocated via new in a different dll.
ACE_TCHAR *new_str = my_hello->new_info ();
ACE_DEBUG ((LM_DEBUG, ACE_TEXT ("Result for new_info(): %s\n"), new_str));
ACE::strdelete (new_str);
// Allocate and free a string allocated via malloc in a different dll.
ACE_TCHAR *malloc_str = my_hello->malloc_info ();
ACE_DEBUG ((LM_DEBUG, ACE_TEXT ("Result for malloc_info(): %s\n"), malloc_str));
ACE_OS::free (malloc_str);
return 0;
}
int dynamic_cast_test (ACE_DLL &dll)
{
Child child;
child.test();
Parent *parent = &child;
void * foo = dll.symbol (ACE_TEXT ("dynamic_cast_test"));
// Cast the void* to long first.
ptrdiff_t tmp = reinterpret_cast<ptrdiff_t> (foo);
PFN pfnAcquire = reinterpret_cast<PFN> (tmp);
if (pfnAcquire == 0)
ACE_ERROR_RETURN ((LM_ERROR,
ACE_TEXT ("%p\n"),
dll.error ()),
-1);
ACE_DEBUG ((LM_DEBUG, ACE_TEXT ("before %@ %@\n"),
&child, dynamic_cast<Child*> (parent)));
if (pfnAcquire (&child) == -1)
ACE_ERROR_RETURN ((LM_ERROR, ACE_TEXT ("dynamic_cast failed.\n")), -1);
return 0;
}
int
run_main (int, ACE_TCHAR *[])
{
ACE_START_TEST (ACE_TEXT ("DLL_Test"));
int retval = 0;
// Protection against this test being run on platforms not supporting Dlls.
#if defined(ACE_HAS_DYNAMIC_LINKING)
ACE_DLL dll;
retval += basic_test (dll);
retval += dynamic_cast_test (dll);
retval += handle_test (dll);
// Call close here so that any errors make it into the log.
dll.close ();
#else
ACE_ERROR ((LM_INFO,
ACE_TEXT ("Dynamically Linkable Libraries not supported on this platform\n")));
#endif /* ACE_HAS_DYNAMIC_LINKING */
ACE_END_TEST;
return retval == 0 ? 0 : 1;
}
|