-
Notifications
You must be signed in to change notification settings - Fork 0
Home
As with any library that has a pure C interface, two methos exist
- Link against libESRI, static or dynamic when building the host app
- Load the dynamic library during runtime, find the functions and call them
An instance represents libESRI and there can be multiple instances per application.
- Create an instance with
EsriCreateInstance()- it returns avoid* - Set the callbacks, see Callbacks
- Run an Instance with
EsriStartInstance(pointerToInstance, port, maxConnections) - When finished, release the instance with
EsriDeleteInstance(pointerToInstance)
Callbacks are used to communicate with the application.
All callbacks are optional, meaning that a nullptr can be passed instead of a function.
| Callback | when | also provides | should return |
|---|---|---|---|
OnProvideWelcomeMessage |
first and once on new client | string for the welcome text | |
OnGetCurrentDirectory |
once after a client connects | string for the prompt text | |
OnProvideCommands |
once after a client connects | string to autocomplete commands | |
OnCommitCommand |
enter is pressed | string of the entire commandline | |
OnAbortCommand |
CTRl-C is pressed | ||
OnExit |
a client disconnects |
All callbacks provide at least two parameter
-
void* handlerto identify which client is meant -
void* userDataspecified by the application
Callbacks are set with EsriSetHandlersForInstance() BEFORE EsriStartInstance()
Thanks to ntshell, libESRI can provide autocomplete with TAB for telnet clients.
libESRI will call OnProvideCommands() to get all commands it should 'know' for autocompletition.
This is a ';' seperated string of all commands.
For example: The application can close and open, then the string would be close;open
See the Limitations section
When OnCommitCommand is called, call EsriPromptTerminal() inside the callback.
OnCommitCommand():
doWork();
EsriPromptTerminal();
return;
When OnCommitCommand is called, do not call EsriPromptTerminal()
This enters command mode of the terminal, where all input is ignored.
When the async task is finished, call EsriPromptTerminal() to re-enable the terminal
OnCommitCommand(void* client):
new thread(doWorkInThread(client));
return;
doWorkInThread(void* client):
DoWork();
EsriPromptTerminal(client);
Be aware that when OnExit() is called for the void* client, the handle will no longer be valid!
When CTRL-C is pressed, the application recevies fnHandlerOnAbortCommand()
Cancel the async work and call EsriPromptTerminal() once it has been fully canceled.
##Internal Commands
libESRI also provides built-in internal commands.
Internal commands have priority over application commands.
This means that an application can not use these command names:
memstat
Is a logical combination: start an async worker but call EsriPromptTerminal() anyway.
With the terminal re-enabled, the user can start more async commands.
Make sure that the calls to EsriSendToTerminal() and are synchronized on the application side since they are not in libESRI.
Sending text to the client is done by calling EsriSendToTerminal(void* client, string text)
This should be done when the terminal is disable, which is between OnCommitCommand() and a call to EsriPromptTerminal()
libESRI inserts linebreak in the welcome message and after every commit command.
This is so that an application using it does not have to add "\r\n" into it's strings.
But for multiple output lines created by complex commands, "\r\n" can of course still be used.
Beware that it's still telnet and that \n won't reset to the beginning of the line and that \r\n is needed
Upon calling EsriStartInstance() a new thread is created to listen to the given tcp port.
For every client that connects, a new port is opened.
This means that callbacks can be called concurrently from different clients.
Locking may be needed when the application does not support that.
The application must fullfill the following promises
- the same instance must not be modified by multiple threads in parallel
-
EsriSendToTerminalon the same handler must not be called by different threads in parallel -
EsriPromptTerminalon the same handler must not be called by different threads in parallel - On the same handler,
EsriSendToTerminalanEsriPromptTerminalmust not be called by different threads in parallel
Calling EsriDeleteInstance() will shutdown all clients gracefully.
It will also join all client threads.
EsriCreateInstance() will call WSAStartup()
EsriDeleteInstance() will call WSACleanup()
This should work since these calls are reference counted.
Meaning: Deleting an instance of ESRI should not unload Winsock from the host application when it's loaded somewhere else.
| What | Limit | defined by | in file |
|---|---|---|---|
| line length in telnet | 64 | NTCONF_EDITOR_MAXLEN | 3rdparty/ntshell/ntconf.h |
| telnet command history | 8 | NTCONF_HISTORY_DEPTH | 3rdparty/ntshell/ntconf.h |
| autocomplete entires | 8 | TEXTCOMPLE_MAXENTRIES | 3rdparty/ntshell/text_complete.h |
| length of one autocomplete command | 32 | TEXTCOMPLETE_MAXLEN | 3rdparty/ntshell/text_complete.h |