NVIDIA Index example code nvidia_logo_transpbg.gif Up
start_application_layer.cpp
Go to the documentation of this file.
1/******************************************************************************
2 * Copyright 2023 NVIDIA Corporation. All rights reserved.
3 *****************************************************************************/
6
7#include <mi/dice.h>
8
9#include <nv/index/iindex.h>
10
11// application layer
12#include <nv/index/app/forwarding_logger.h>
13#include <nv/index/app/iapplication_layer.h>
14#include <nv/index/app/iapplication_layer_plugin.h>
15#include <nv/index/app/iapplication_layer_component.h>
16#include <nv/index/app/istring_dict.h>
17
18#include <vector>
19#include <cstdio>
20
21#ifndef MI_PLATFORM_WINDOWS
22#include <dlfcn.h>
23#include <netinet/in.h>
24#include <sys/time.h>
25#else
26#include <Winsock2.h>
27#include <windows.h>
28#endif // MI_PLATFORM_WINDOWS
29
30#ifdef LINUX
31#include <unistd.h>
32#endif // LINUX
33
34//----------------------------------------------------------------------
35namespace { // anonymous namespace for the local functions
36//----------------------------------------------------------------------
37// check_success's message function
38void exit_with_fail_message(const char* msg, const char* filename, int line)
39{
40 fprintf(stderr, "Error in file %s, line %d: \"%s\".\n", filename, line, msg);
41 exit(EXIT_FAILURE);
42}
43
44//----------------------------------------------------------------------
45// Helper macro. Checks whether the expression is true and if not prints a message and exits.
46#define check_success(expr) \
47 { if (!(expr)) { exit_with_fail_message(#expr, __FILE__, __LINE__); } }
48
49//----------------------------------------------------------------------
50// load so/dll and instantiate interface
51template <class Interface>
52Interface* load_and_get_interface(
53 const std::string& lib_file_basename,
54 const std::string& lib_symbol_name)
55{
56#ifdef MI_PLATFORM_WINDOWS
57
58 // Windows
59 const std::string lib_file_name = lib_file_basename + ".dll";
60
61 void* handle = LoadLibrary(TEXT(lib_file_name.c_str()));
62 if (!handle)
63 {
64 printf("error: Could not retrieve a handle to the %s library\n", lib_file_name.c_str());
65 return NULL;
66 }
67 void* symbol = GetProcAddress((HMODULE)handle, lib_symbol_name.c_str());
68 if (!symbol)
69 {
70 printf("error: Could not retrieve the entry point into the %s library\n", lib_file_name.c_str());
71 return NULL;
72 }
73#else // MI_PLATFORM_WINDOWS
74
75 // Linux
76 const std::string lib_file_name = lib_file_basename + ".so";
77 void* handle = dlopen(lib_file_name.c_str(), RTLD_LAZY);
78 if (!handle)
79 {
80 printf("error: iindex: handle: %s\n", dlerror());
81 return 0;
82 }
83
84 void* symbol = dlsym(handle, lib_symbol_name.c_str());
85 if (!symbol)
86 {
87 printf("error: iindex: symbol: %s\n", dlerror());
88 return NULL;
89 }
90#endif // MI_PLATFORM_WINDOWS
91
92 return nv::index::nv_factory<Interface>(symbol);
93}
94
95//----------------------------------------------------------------------
96// Initialize the logger of IndeX
97void initialize_log_module(nv::index::IIndex* iindex)
98{
99 check_success(iindex != 0);
100
101 mi::base::Handle<mi::neuraylib::ILogging_configuration> logging_configuration(
102 iindex->get_api_component<mi::neuraylib::ILogging_configuration>());
103 check_success(logging_configuration.is_valid_interface());
104
105 // Log locally
106 logging_configuration->set_log_locally(true);
107
108 // If adding receiving logger
109 // mi::base::Handle<mi::base::ILogger> receiving_logger(new My_receiving_logger());
110 // logging_configuration->set_receiving_logger(receiving_logger.get());
111
112 // set log level, also for all categories
113 logging_configuration->set_log_level(mi::base::MESSAGE_SEVERITY_VERBOSE);
114 logging_configuration->set_log_level_by_category("ALL", mi::base::MESSAGE_SEVERITY_VERBOSE);
115 INFO_LOG << "Set logging level to " << mi::base::MESSAGE_SEVERITY_VERBOSE;
116}
117
118//----------------------------------------------------------------------
119// configure IApplication_layer
120void configure_application_layer(nv::index::app::IApplication_layer* application_layer)
121{
122 check_success(application_layer != 0);
123
124 // configuration (optional) for IApplication_layer
125 {
126 mi::base::Handle<nv::index::app::IString_dict> config(
127 application_layer->create<nv::index::app::IString_dict>());
128 const mi::Sint32 ret = application_layer->set_configuration(config.get());
129 INFO_LOG << "RET: " << ret;
130 check_success(ret == 0);
131 }
132}
133
134//----------------------------------------------------------------------
135// Load and configure application_layer components
136void load_application_layer_components(nv::index::app::IApplication_layer* application_layer)
137{
138 check_success(application_layer != 0);
139
140 // Load application layer components .dll/so
141 const char* component_dso_basename_vec[] = {
142 "libnvindex_application_layer_example_template_component",
143 "libnvindex_application_layer_canvas_infrastructure",
144 "libnvindex_application_layer_canvas_infrastructure_opengl",
145 "libnvindex_application_layer_command_database",
146 "libnvindex_application_layer_command_replay",
147 "libnvindex_application_layer_html5_integration",
148 "libnvindex_application_layer_scene_management_center",
149 // "libnvindex_application_layer_io", For is_application_layer_component_registered() test.
150 0,
151 };
152
153 for (mi::Size i = 0; component_dso_basename_vec[i] != 0; ++i)
154 {
155 const std::string dso_basename = component_dso_basename_vec[i];
156 const bool is_loaded = application_layer->load_application_layer_component(dso_basename.c_str());
157 if (is_loaded)
158 {
159 nv::index::app::IApplication_layer_component* component
160 = application_layer->get_application_layer_component(dso_basename.c_str());
161 check_success(component != 0);
162 INFO_LOG << "Loaded NVIDIA IndeX application layer component: " << dso_basename
163 << " (" << component->get_component_name() << ")";
164
165 // component configuration
166 mi::base::Handle<nv::index::app::IString_dict> config(
167 application_layer->create<nv::index::app::IString_dict>());
168 // configuration if any
169 // config->insert_string_key_value("config_key", "config_value");
170 const bool is_ok = component->set_configuration(config.get());
171 check_success(is_ok);
172 }
173 }
174
175 // Test is_application_layer_component_registered()
176 // Already loaded component check
177 check_success (application_layer->is_application_layer_component_registered("libnvindex_application_layer_scene_management_center"));
178
179 // Not yet loaded component check
180 check_success (!application_layer->is_application_layer_component_registered("libnvindex_application_layer_io"));
181
182 // Load io
183 check_success(application_layer->load_application_layer_component("libnvindex_application_layer_io"));
184
185 // Now io has been loaded
186 check_success (application_layer->is_application_layer_component_registered("libnvindex_application_layer_io"));
187}
188
189//----------------------------------------------------------------------
190// Load and configure application_layer plugins
191void load_application_layer_plugins(nv::index::app::IApplication_layer* application_layer)
192{
193 check_success(application_layer != 0);
194 // Loading application layer plugins .dll/so
195 const char* plugin_dso_basename_vec[] = {
196 "libnvindex_plugin_advanced_stats",
197 "libnvindex_plugin_base_importer",
198 // For Test "libnvindex_plugin_example_template",
199 0,
200 };
201
202 for (mi::Size i = 0; plugin_dso_basename_vec[i] != 0; ++i)
203 {
204 const std::string dso_basename = plugin_dso_basename_vec[i];
205 const bool is_loaded = application_layer->load_application_layer_plugin(dso_basename.c_str());
206 if (is_loaded)
207 {
208 nv::index::app::IApplication_layer_plugin* plugin
209 = application_layer->get_application_layer_plugin(dso_basename.c_str());
210 check_success(plugin != 0);
211 INFO_LOG << "Loaded NVIDIA IndeX application layer plugin: " << dso_basename
212 << " (" << plugin->get_plugin_name() << ")";
213
214 // plugin configuration
215 mi::base::Handle<nv::index::app::IString_dict> config(
216 application_layer->create<nv::index::app::IString_dict>());
217 // configuration if any
218 // config->insert_string_key_value("config_key", "config_value");
219 const bool is_ok = plugin->set_configuration(config.get());
220 check_success(is_ok);
221 }
222 }
223
224 // Test is_application_layer_plugin_registered()
225 // Already loaded plugin check
226 check_success (application_layer->is_application_layer_plugin_registered("libnvindex_plugin_base_importer"));
227
228 // Not yet loaded plugin check
229 check_success (!application_layer->is_application_layer_plugin_registered("libnvindex_plugin_example_template"));
230
231 // Load example_template
232 check_success(application_layer->load_application_layer_plugin("libnvindex_plugin_example_template"));
233
234 // Now example_template io has been loaded
235 check_success (application_layer->is_application_layer_plugin_registered("libnvindex_plugin_example_template"));
236}
237
238//----------------------------------------------------------------------
239} // namespace anonymous
240//----------------------------------------------------------------------
241int main(int argc, char* argv[])
242{
243 // Load IndeX library and get IIndex
244 const std::string index_lib_basename = "libnvindex";
245 const std::string index_lib_symbol_name = "nv_factory";
246 mi::base::Handle<nv::index::IIndex> iindex(
247 load_and_get_interface<nv::index::IIndex>(index_lib_basename, index_lib_symbol_name));
248 check_success(iindex.is_valid_interface());
249
250 // Load Application_layer library and get IApplication_layer
251 const std::string applayer_lib_basename = "libnvindex_application_layer_application_layer";
252 const std::string applayer_lib_symbol_name = "nvindex_application_layer_application_layer_factory";
253 mi::base::Handle<nv::index::app::IApplication_layer> applayer(
254 load_and_get_interface<nv::index::app::IApplication_layer>(
255 applayer_lib_basename, applayer_lib_symbol_name));
256 check_success(applayer.is_valid_interface());
257
258 // logging configuration of IIndex
259 initialize_log_module(iindex.get());
260 INFO_LOG << "NVIDIA IndeX version: "<< iindex->get_version();
261
262 // initialize application layer
263 applayer->initialize(iindex.get());
264
265 // configure application_layer interface itself.
266 configure_application_layer(applayer.get());
267
268 // load application_layer components
269 load_application_layer_components(applayer.get());
270
271 // load application_layer (including third party) plugins
272 load_application_layer_plugins(applayer.get());
273
274 // start IndeX service and application_layer service
275 const mi::Sint32 index_ret = iindex->start();
276 check_success(index_ret == 0);
277 INFO_LOG << "IndeX service has been started.";
278
279 //---------------------------------------------------------------------
280 // start application layer
281 const mi::Sint32 applayer_ret = applayer->start();
282 check_success(applayer_ret == 0);
283 INFO_LOG << "Application_layer service has been started.";
284
285 //---------------------------------------------------------------------
286 // shutdown application layer
287 INFO_LOG << "shutdown application_layer";
288 applayer->shutdown();
289 applayer->deinitialize();
290 applayer.reset();
291
292 // removing logger from IIndex
293 {
294 mi::base::Handle< mi::neuraylib::ILogging_configuration > logging_configuration(
295 iindex->get_api_component< mi::neuraylib::ILogging_configuration >());
296 check_success(logging_configuration.is_valid_interface());
297 logging_configuration->set_receiving_logger(0);
298 }
299
300 // shutdown index
301 mi::Sint32 index_shutdown = iindex->shutdown();
302 if (index_shutdown != 0)
303 {
304 fprintf(stderr, "error: failed NVIDIA IndeX shutdown (code: %d)\n", index_shutdown);
305 }
306 iindex.reset();
307
308 return 0;
309}
int main(int argc, char *argv[])
#define check_success(expr)