/******************************************************************************
* Copyright 1986, 2016 NVIDIA Corporation. All rights reserved.
*****************************************************************************/
// examples/example_shared.h
//
// Code shared by all examples
#ifndef EXAMPLE_SHARED_H
#define EXAMPLE_SHARED_H
#include <cstdio>
#include <cstdlib>
#include <mi/neuraylib.h>
#ifdef MI_PLATFORM_WINDOWS
#include <mi/base/miwindows.h>
#else
#include <dlfcn.h>
#include <unistd.h>
#endif
#include "authentication.h"
// Pointer to the DSO handle. Cached here for unload().
void* g_dso_handle = 0;
// Pointer to the DSO filename. Cached here for unload().
const char* g_filename = 0;
// Ensures that the console with the log messages does not close immediately. On Windows, the user
// is asked to press enter. On other platforms, nothing is done as the examples are most likely
// started from the console anyway.
void keep_console_open() {
#ifdef MI_PLATFORM_WINDOWS
if( IsDebuggerPresent()) {
fprintf( stderr, "Press enter to continue . . . \n");
fgetc( stdin);
}
#endif // MI_PLATFORM_WINDOWS
}
// Helper macro. Checks whether the expression is true and if not prints a message and exits.
#define check_success( expr) \
do { \
if( !(expr)) { \
fprintf( stderr, "Error in file %s, line %u: \"%s\".\n", __FILE__, __LINE__, #expr); \
keep_console_open(); \
exit( EXIT_FAILURE); \
} \
} while( false)
// Helper function similar to check_success(), but specifically for the result of
// #mi::neuraylib::INeuray::start().
void check_start_success( mi::Sint32 result)
{
if( result == 0)
return;
fprintf( stderr, "mi::neuraylib::INeuray::start() failed with return code %d.\n", result);
fprintf( stderr, "Typical failure reasons are related to authentication, see the\n");
fprintf( stderr, "documentation of this method for details.\n");
keep_console_open();
exit( EXIT_FAILURE);
}
// printf() format specifier for arguments of type LPTSTR (Windows only).
#ifdef MI_PLATFORM_WINDOWS
#ifdef UNICODE
#define FMT_LPTSTR "%ls"
#else // UNICODE
#define FMT_LPTSTR "%s"
#endif // UNICODE
#endif // MI_PLATFORM_WINDOWS
// Loads the neuray library and calls the main factory function.
//
// This convenience function loads the neuray DSO, locates and calls the #mi_neuray_factory()
// function. It returns an instance of the main #mi::neuraylib::INeuray interface. It also
// supplies a authentication key (only needed by some variants of the neuray library).
// The function may be called only once.
//
// \param filename The file name of the DSO. It is feasible to pass \c NULL, which uses a
// built-in default value.
// \return A pointer to an instance of the main #mi::neuraylib::INeuray interface
mi::neuraylib::INeuray* load_and_get_ineuray( const char* filename = 0)
{
#ifdef MI_PLATFORM_WINDOWS
if( !filename)
filename = "libneuray.dll";
g_filename = filename;
void* handle = LoadLibraryA((LPSTR) filename);
if( !handle) {
LPTSTR buffer = 0;
LPTSTR message = TEXT("unknown failure");
DWORD error_code = GetLastError();
if( FormatMessage( FORMAT_MESSAGE_ALLOCATE_BUFFER | FORMAT_MESSAGE_FROM_SYSTEM |
FORMAT_MESSAGE_IGNORE_INSERTS, 0, error_code,
MAKELANGID( LANG_NEUTRAL, SUBLANG_DEFAULT), (LPTSTR) &buffer, 0, 0))
message = buffer;
fprintf( stderr, "Failed to load library (%u): " FMT_LPTSTR, error_code, message);
if( buffer)
LocalFree( buffer);
return 0;
}
void* symbol = GetProcAddress((HMODULE) handle, "mi_neuray_factory");
if( !symbol) {
LPTSTR buffer = 0;
LPTSTR message = TEXT("unknown failure");
DWORD error_code = GetLastError();
if( FormatMessage( FORMAT_MESSAGE_ALLOCATE_BUFFER | FORMAT_MESSAGE_FROM_SYSTEM |
FORMAT_MESSAGE_IGNORE_INSERTS, 0, error_code,
MAKELANGID( LANG_NEUTRAL, SUBLANG_DEFAULT), (LPTSTR) &buffer, 0, 0))
message = buffer;
fprintf( stderr, "GetProcAddress error (%u): " FMT_LPTSTR, error_code, message);
if( buffer)
LocalFree( buffer);
return 0;
}
#else // MI_PLATFORM_WINDOWS
if( !filename)
filename = "libneuray.so";
g_filename = filename;
#ifdef MI_PLATFORM_MACOSX
void* handle = dlopen( filename, RTLD_LAZY);
#else // MI_PLATFORM_MACOSX
void* handle = dlopen( filename, RTLD_LAZY|RTLD_DEEPBIND);
#endif // MI_PLATFORM_MACOSX
if( !handle) {
fprintf( stderr, "%s\n", dlerror());
return 0;
}
void* symbol = dlsym( handle, "mi_neuray_factory");
if( !symbol) {
fprintf( stderr, "%s\n", dlerror());
return 0;
}
#endif // MI_PLATFORM_WINDOWS
g_dso_handle = handle;
typedef mi::neuraylib::INeuray* (INeuray_factory)
(mi::neuraylib::IAllocator*, mi::Uint32);
INeuray_factory* factory = (INeuray_factory*) symbol;
mi::neuraylib::INeuray* neuray = factory( 0, MI_NEURAYLIB_API_VERSION);
if( neuray)
check_success( authenticate( neuray) == 0);
return neuray;
}
// Unloads the neuray library.
bool unload()
{
#ifdef MI_PLATFORM_WINDOWS
int result = FreeLibrary( (HMODULE)g_dso_handle);
if( result == 0) {
LPTSTR buffer = 0;
LPTSTR message = TEXT("unknown failure");
DWORD error_code = GetLastError();
if( FormatMessage( FORMAT_MESSAGE_ALLOCATE_BUFFER | FORMAT_MESSAGE_FROM_SYSTEM |
FORMAT_MESSAGE_IGNORE_INSERTS, 0, error_code,
MAKELANGID( LANG_NEUTRAL, SUBLANG_DEFAULT), (LPTSTR) &buffer, 0, 0))
message = buffer;
fprintf( stderr, "Failed to unload library (%u): " FMT_LPTSTR, error_code, message);
if( buffer)
LocalFree( buffer);
return false;
}
return true;
#else
int result = dlclose( g_dso_handle);
if( result != 0)
fprintf( stderr, "%s\n", dlerror());
#ifdef MI_PLATFORM_MACOSX
void* handle = dlopen( g_filename, RTLD_LAZY|RTLD_NOLOAD);
#else // MI_PLATFORM_MACOSX
void* handle = dlopen( g_filename, RTLD_LAZY|RTLD_NOLOAD|RTLD_DEEPBIND);
#endif // MI_PLATFORM_MACOSX
return handle == 0;
#endif
}
// Sleep the indicated number of seconds.
void sleep_seconds( mi::Uint32 seconds)
{
#ifdef MI_PLATFORM_WINDOWS
Sleep( seconds * 1000);
#else
sleep( seconds);
#endif
}
// Map snprintf to _snprintf on Windows.
#ifdef MI_PLATFORM_WINDOWS
#define snprintf _snprintf
#endif
#endif // MI_EXAMPLE_SHARED_H