NVIDIA Iray API — software examples nvidia_logo_transpbg.gif Up
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Groups Pages
example_shared.h
Go to the documentation of this file.
1 /******************************************************************************
2  * Copyright 2020 NVIDIA Corporation. All rights reserved.
3  *****************************************************************************/
4 
5 // examples/example_shared.h
6 //
7 // Code shared by all examples
8 
9 #ifndef EXAMPLE_SHARED_H
10 #define EXAMPLE_SHARED_H
11 
12 #include <cstdio>
13 #include <cstdlib>
14 
15 #include <mi/neuraylib.h>
16 
17 #ifdef MI_PLATFORM_WINDOWS
18 #include <mi/base/miwindows.h>
19 #else
20 #include <dlfcn.h>
21 #include <unistd.h>
22 #endif
23 
24 #include "authentication.h"
25 
26 // Pointer to the DSO handle. Cached here for unload().
27 void* g_dso_handle = 0;
28 
29 // Ensures that the console with the log messages does not close immediately. On Windows, the user
30 // is asked to press enter. On other platforms, nothing is done as the examples are most likely
31 // started from the console anyway.
33 #ifdef MI_PLATFORM_WINDOWS
34  if( IsDebuggerPresent()) {
35  fprintf( stderr, "Press enter to continue . . . \n");
36  fgetc( stdin);
37  }
38 #endif // MI_PLATFORM_WINDOWS
39 }
40 
41 // Helper macro. Checks whether the expression is true and if not prints a message and exits.
42 #define check_success( expr) \
43  do { \
44  if( !(expr)) { \
45  fprintf( stderr, "Error in file %s, line %u: \"%s\".\n", __FILE__, __LINE__, #expr); \
46  keep_console_open(); \
47  exit( EXIT_FAILURE); \
48  } \
49  } while( false)
50 
51 // Helper function similar to check_success(), but specifically for the result of
52 // #mi::neuraylib::INeuray::start().
54 {
55  if( result == 0)
56  return;
57  fprintf( stderr, "mi::neuraylib::INeuray::start() failed with return code %d.\n", result);
58  fprintf( stderr, "Typical failure reasons are related to authentication, see the\n");
59  fprintf( stderr, "documentation of this method for details.\n");
61  exit( EXIT_FAILURE);
62 }
63 
64 // printf() format specifier for arguments of type LPTSTR (Windows only).
65 #ifdef MI_PLATFORM_WINDOWS
66 #ifdef UNICODE
67 #define FMT_LPTSTR "%ls"
68 #else // UNICODE
69 #define FMT_LPTSTR "%s"
70 #endif // UNICODE
71 #endif // MI_PLATFORM_WINDOWS
72 
73 // Loads the neuray library and calls the main factory function.
74 //
75 // This convenience function loads the neuray DSO, locates and calls the #mi_factory()
76 // function. It returns an instance of the main #mi::neuraylib::INeuray interface. It also
77 // supplies a authentication key (only needed by some variants of the neuray library).
78 // The function may be called only once.
79 //
80 // \param filename The file name of the DSO. It is feasible to pass \c NULL, which uses a
81 // built-in default value.
82 // \return A pointer to an instance of the main #mi::neuraylib::INeuray interface
83 mi::neuraylib::INeuray* load_and_get_ineuray( const char* filename = 0)
84 {
85  if( !filename)
86  filename = "libneuray" MI_BASE_DLL_FILE_EXT;
87 #ifdef MI_PLATFORM_WINDOWS
88  void* handle = LoadLibraryA((LPSTR) filename);
89  if( !handle) {
90  LPTSTR buffer = 0;
91  LPTSTR message = TEXT("unknown failure");
92  DWORD error_code = GetLastError();
93  if( FormatMessage( FORMAT_MESSAGE_ALLOCATE_BUFFER | FORMAT_MESSAGE_FROM_SYSTEM |
94  FORMAT_MESSAGE_IGNORE_INSERTS, 0, error_code,
95  MAKELANGID( LANG_NEUTRAL, SUBLANG_DEFAULT), (LPTSTR) &buffer, 0, 0))
96  message = buffer;
97  fprintf( stderr, "Failed to load library (%u): " FMT_LPTSTR, error_code, message);
98  if( buffer)
99  LocalFree( buffer);
100  return 0;
101  }
102  void* symbol = GetProcAddress((HMODULE) handle, "mi_factory");
103  if( !symbol) {
104  LPTSTR buffer = 0;
105  LPTSTR message = TEXT("unknown failure");
106  DWORD error_code = GetLastError();
107  if( FormatMessage( FORMAT_MESSAGE_ALLOCATE_BUFFER | FORMAT_MESSAGE_FROM_SYSTEM |
108  FORMAT_MESSAGE_IGNORE_INSERTS, 0, error_code,
109  MAKELANGID( LANG_NEUTRAL, SUBLANG_DEFAULT), (LPTSTR) &buffer, 0, 0))
110  message = buffer;
111  fprintf( stderr, "GetProcAddress error (%u): " FMT_LPTSTR, error_code, message);
112  if( buffer)
113  LocalFree( buffer);
114  return 0;
115  }
116 #else // MI_PLATFORM_WINDOWS
117  void* handle = dlopen( filename, RTLD_LAZY);
118  if( !handle) {
119  fprintf( stderr, "%s\n", dlerror());
120  return 0;
121  }
122  void* symbol = dlsym( handle, "mi_factory");
123  if( !symbol) {
124  fprintf( stderr, "%s\n", dlerror());
125  return 0;
126  }
127 #endif // MI_PLATFORM_WINDOWS
128  g_dso_handle = handle;
129 
130  mi::neuraylib::INeuray* neuray = mi::neuraylib::mi_factory<mi::neuraylib::INeuray>( symbol);
131  if( !neuray)
132  {
134  mi::neuraylib::mi_factory<mi::neuraylib::IVersion>( symbol));
135  if( !version)
136  fprintf( stderr, "Error: Incompatible library.\n");
137  else
138  fprintf( stderr, "Error: Library version %s does not match header version %s.\n",
140  return 0;
141  }
142 
143  check_success( authenticate( neuray) == 0);
144  return neuray;
145 }
146 
147 // Unloads the neuray library.
148 bool unload()
149 {
150 #ifdef MI_PLATFORM_WINDOWS
151  int result = FreeLibrary( (HMODULE)g_dso_handle);
152  if( result == 0) {
153  LPTSTR buffer = 0;
154  LPTSTR message = TEXT("unknown failure");
155  DWORD error_code = GetLastError();
156  if( FormatMessage( FORMAT_MESSAGE_ALLOCATE_BUFFER | FORMAT_MESSAGE_FROM_SYSTEM |
157  FORMAT_MESSAGE_IGNORE_INSERTS, 0, error_code,
158  MAKELANGID( LANG_NEUTRAL, SUBLANG_DEFAULT), (LPTSTR) &buffer, 0, 0))
159  message = buffer;
160  fprintf( stderr, "Failed to unload library (%u): " FMT_LPTSTR, error_code, message);
161  if( buffer)
162  LocalFree( buffer);
163  return false;
164  }
165  return true;
166 #else
167  int result = dlclose( g_dso_handle);
168  if( result != 0) {
169  fprintf( stderr, "%s\n", dlerror());
170  return false;
171  }
172  return true;
173 #endif
174 }
175 
176 // Sleep the indicated number of seconds.
178 {
179 #ifdef MI_PLATFORM_WINDOWS
180  Sleep( static_cast<DWORD>( seconds * 1000));
181 #else
182  usleep( static_cast<useconds_t>( seconds * 1000000));
183 #endif
184 }
185 
186 // Map snprintf to _snprintf on Windows.
187 #ifdef MI_PLATFORM_WINDOWS
188 #define snprintf _snprintf
189 #endif
190 
191 #endif // MI_EXAMPLE_SHARED_H