I Need to Reload H&r Block Tax Software Deluxe + State 2016 but Do Not Want to Pay for It Again
cr.h
A single file header-only live reload solution for C, written in C++:
- elementary public API, 3 functions to employ only (and another to export);
- works and tested on Linux, MacOSX and Windows;
- automatic crash protection;
- automatic static land transfer;
- based on dynamic reloadable binary (.so/.dylib/.dll);
- support multiple plugins;
- MIT licensed;
Build Status:
Platform | Build Status |
---|---|
Linux | |
Windows |
Note that the just file that matters is cr.h
.
This file contains the documentation in markdown, the license, the implementation and the public api. All other files in this repository are supporting files and can be safely ignored.
Example
A (sparse) host application executable will brand use of cr
to manage live-reloading of the real application in the form of dynamic loadable binary, a host would be something like:
#define CR_HOST // required in the host only and before including cr.h #include "../cr.h" int principal(int argc, char *argv[]) { // the host application should initalize a plugin with a context, a plugin cr_plugin ctx; // the full path to the live-reloadable awarding cr_plugin_open(ctx, "c:/path/to/build/game.dll" ); // call the update function at any frequency matters to you lot, this will requite // the real application a adventure to run while (!cr_plugin_update(ctx)) { // exercise anything yous need to do on host side (ie. windowing and input stuff?) } // at the terminate do not forget to cleanup the plugin context cr_plugin_close(ctx); return 0; }
While the guest (real application), would be similar:
CR_EXPORT int cr_main(struct cr_plugin *ctx, enum cr_op operation) { assert(ctx); switch (operation) { instance CR_LOAD: return on_load(...); // loading back from a reload example CR_UNLOAD: return on_unload(...); // preparing to a new reload instance CR_CLOSE: ...; // the plugin will shut and not reload anymore } // CR_STEP return on_update(...); }
Changelog
2020-01-09
- Deprecated
cr_plugin_load
in favor tocr_plugin_open
for consistency withcr_plugin_close
. See upshot #49. - Minor documentation improvements.
2018-xi-17
- Support to OSX finished, cheers to MESH Consultants Inc.
- Added a new possible failure
CR_BAD_IMAGE
in instance the binary file is stil non set even if its timestamp inverse. This could happen if generating the file (compiler or copying) was slow. - Windows: Fix outcome with as well long paths causing the PDB patch process to fail, causing the reload process to fail.
- Possible breaking change: Fix rollback flow. Before, during a rollback (for whatsoever reason) 2 versions were decremented ane-shot so that the in following load, the version would crash-land over again getting us finer on the previous version, simply in some cases not related to crashes this wasn't completely valid (run across
CR_BAD_IMAGE
). At present the version is decremented one fourth dimension in the crash handler and then some other time during the rollback and and then be bumped once more. A rollback due an incomplete image will not incorrectly rollback 2 versions, it will keep at the same version retrying the load until the epitome is valid (copy or compiler finished writing to it). This may impact electric current uses ofcr
if theversion
info is used duringCR_UNLOAD
equally it will now be a unlike value.
Samples
Two simple samples can be found in the samples
directory.
The kickoff is i is a simple console application that demonstrate some basic static states working between instances and basic crash handling tests. Print to output is used to show what is happening.
The second one demonstrates how to live-reload an opengl awarding using Dear ImGui. Some state lives in the host side while most of the code is in the invitee side.
Running Samples and Tests
The samples and tests uses the fips build system. It requires Python and CMake.
$ ./fips build # will generate and build all artifacts $ ./fips run crTest # To run tests $ ./fips run imgui_host # To run imgui sample # open a new panel, then modify imgui_guest.cpp $ ./fips make imgui_guest # to build and force imgui sample live reload
Documentation
int (*cr_main)(struct cr_plugin *ctx, enum cr_op operation)
This is the role pointer to the dynamic loadable binary entry point function.
Arguments
-
ctx
pointer to a context that will be passed fromhost
to theguest
containing valuable information about the current loaded version, failure reason and user information. For more info meetcr_plugin
. -
operation
which operation is being executed, seecr_op
.
Return
- A negative value indicating an error, forcing a rollback to happen and failure being set to
CR_USER
. 0 or a positive value that will be passed to thehost
process.
bool cr_plugin_open(cr_plugin &ctx, const char *fullpath)
Loads and initialize the plugin.
Arguments
-
ctx
a context that will manage the plugin internal information and user data. -
fullpath
total path with filename to the loadable binary for the plugin orNULL
.
Return
-
true
in instance of success,false
otherwise.
void cr_set_temporary_path(cr_plugin& ctx, const std::string &path)
Sets temporary path to which temporary copies of plugin will be placed. Should be called immediately after cr_plugin_open()
. If temporary
path is non set, temporary copies of the file will be copied to the same directory where the original file is located.
Arguments
-
ctx
a context that will manage the plugin internal data and user information. -
path
a full path to an existing directory which volition exist used for storing temporary plugin copies.
int cr_plugin_update(cr_plugin &ctx, bool reloadCheck = true)
This function will call the plugin cr_main
function. It should be called as frequently as the core logic/application needs.
Arguments
-
ctx
the current plugin context information. -
reloadCheck
optional: do a disk check (stat()) to encounter if the dynamic library needs a reload.
Render
- -1 if a failure happened during an update;
- -2 if a failure happened during a load or unload;
- anything else is returned directly from the plugin
cr_main
.
void cr_plugin_close(cr_plugin &ctx)
Cleanup internal states once the plugin is not required anymore.
Arguments
-
ctx
the current plugin context data.
cr_op
Enum indicating the kind of pace that is being executed by the host
:
-
CR_LOAD
A load acquired by reload is being executed, tin be used to restore any saved internal state. This does not happen when a plugin is loaded for the first time as there is no country to restore; -
CR_STEP
An application update, this is the normal and nigh frequent operation; -
CR_UNLOAD
An unload for reloading the plugin will be executed, giving the application one chance to shop whatever required data; -
CR_CLOSE
Used when closing the plugin, This works likeCR_UNLOAD
simply noCR_LOAD
should exist expected later on;
cr_plugin
The plugin instance context struct.
-
p
opaque pointer for internal cr data; -
userdata
may be used by the user to laissez passer information betwixt reloads; -
version
incremetal number for each succeded reload, starting at 1 for the first load. The version will change during a crash treatment process; -
failure
used past the crash protection system, volition hold the terminal failure error code that caused a rollback. Seecr_failure
for more info on possible values;
cr_failure
If a crash in the loadable binary happens, the crash handler will betoken the reason of the crash with ane of these:
-
CR_NONE
No mistake; -
CR_SEGFAULT
Segmentation fault.SIGSEGV
on Linux/OSX orEXCEPTION_ACCESS_VIOLATION
on Windows; -
CR_ILLEGAL
In case of illegal educational activity.SIGILL
on Linux/OSX orEXCEPTION_ILLEGAL_INSTRUCTION
on Windows; -
CR_ABORT
Abort,SIGBRT
on Linux/OSX, not used on Windows; -
CR_MISALIGN
Bus error,SIGBUS
on Linux/OSX orEXCEPTION_DATATYPE_MISALIGNMENT
on Windows; -
CR_BOUNDS
IsEXCEPTION_ARRAY_BOUNDS_EXCEEDED
, Windows only; -
CR_STACKOVERFLOW
IsEXCEPTION_STACK_OVERFLOW
, Windows only; -
CR_STATE_INVALIDATED
StaticCR_STATE
management safety failure; -
CR_BAD_IMAGE
The plugin is not a valid paradigm (i.e. the compiler may still writing information technology); -
CR_OTHER
Other indicate, Linux only; -
CR_USER
User error (for negative values returned fromcr_main
);
CR_HOST
ascertain
This ascertain should be used earlier including the cr.h
in the host
, if CR_HOST
is not defined, cr.h
will work as a public API header file to be used in the guest
implementation.
Optionally CR_HOST
may also be defined to i of the post-obit values every bit a way to configure the prophylactic
operation manner for automatic static state management (CR_STATE
):
-
CR_SAFEST
Will validate address and size of the country data sections during reloads, if anything changes the load will rollback; -
CR_SAFE
Will validate only the size of the state section, this hateful that the address of the statics may change (and it is all-time to avoid property any pointer to static stuff); -
CR_UNSAFE
Will validate nothing merely that the size of department fits, may not be necessarelly exact (growing is acceptable simply shrinking isn't), this is the default behavior; -
CR_DISABLE
Completely disable automatic static state management;
CR_STATE
macro
Used to tag a global or local static variable to be saved and restored during a reload.
Usage
static bool CR_STATE bInitialized = simulated;
Overridable macros
You can ascertain these macros before including cr.h in host (CR_HOST) to customize cr.h memory allocations and other behaviours:
-
CR_MAIN_FUNC
: changes 'cr_main' symbol to user-defined function name. default: #define CR_MAIN_FUNC "cr_main" -
CR_ASSERT
: override assert. default: #ascertain CA_ASSERT(due east) assert(due east) -
CR_REALLOC
: override libc's realloc. default: #ascertain CR_REALLOC(ptr, size) ::realloc(ptr, size) -
CR_MALLOC
: override libc'south malloc. default: #ascertain CR_MALLOC(size) ::malloc(size) -
CR_FREE
: override libc's gratis. default: #define CR_FREE(ptr) ::free(ptr) -
CR_DEBUG
: outputs debug messages in CR_ERROR, CR_LOG and CR_TRACE -
CR_ERROR
: logs debug messages to stderr. default (CR_DEBUG only): #define CR_ERROR(...) fprintf(stderr, VA_ARGS) -
CR_LOG
: logs debug messages. default (CR_DEBUG only): #ascertain CR_LOG(...) fprintf(stdout, VA_ARGS) -
CR_TRACE
: prints part calls. default (CR_DEBUG only): #ascertain CR_TRACE(...) fprintf(stdout, "CR_TRACE: %s\northward", Office)
FAQ / Troubleshooting
Q: Why?
A: Read about why I made this here.
Q: My application asserts/crash when freeing heap data allocated inside the dll, what is happening?
A: Make sure both your awarding host and your dll are using the dynamic run-time (/Doc or /MDd) as whatever data allocated in the heap must exist freed with the same allocator instance, by sharing the run-time between guest and host you will guarantee the same allocator is being used.
Q: Can we load multiple plugins at the aforementioned fourth dimension?
A: Yes. This should work without problems on Windows. On Linux and OSX there may be bug with crash treatment
Q: You said this wouldn't lock my PDB, merely it still locks! Why?
If you lot had to load the dll before cr
for any reason, Visual Studio may yet hold a lock to the PDB. You may exist having this issue and the solution is here.
Q: Hot-reload is not working at all, what I'thousand doing wrong?
Showtime, exist certain that your build system is non interfering by somewhat still linking to your shared library. There are so many things that can become wrong and you need to be certain only cr
will deal with your shared library. On linux, for more than info on how to observe what is happening, cheque this outcome.
Q: How much tin I change things in the plugin without risking breaking everything?
cr
is C
reloader and dealing with C it assume simple things will by and large work.
The problem is how the linker will determine practice rearrange things accordingly the amount of changes you do in the code. For incremental and localized changes I never had whatever problems, in full general I inappreciably had any bug at all past writing normal C code. Now, when things start to become more complex and adjoining C++, it becomes riskier. If yous need practise complex things, I advise checking RCCPP and reading this PDF and my original weblog post about cr
here.
With all these data y'all'll be able to decide which is better to your utilise case.
cr
Sponsors
MESH Consultants Inc.
For sponsoring the port of cr
to the MacOSX.
Contributors
Danny Grein
Rokas Kupstys
Noah Rinehart
Niklas Lundberg
Sepehr Taghdisian
Robert Gabriel Jakabosky
@pixelherodev
Contributing
We welcome ALL contributions, there is no minor things to contribute with, fifty-fifty one alphabetic character typo fixes are welcome.
The merely things we require is to test thoroughly, maintain code manner and keeping documentation upward-to-date.
Also, accepting and like-minded to release whatever contribution nether the aforementioned license.
License
The MIT License (MIT)
Copyright (c) 2017 Danny Angelo Carminati Grein
Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, alter, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:
The in a higher place copyright observe and this permission find shall be included in all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "Every bit IS", WITHOUT WARRANTY OF Any KIND, Limited OR IMPLIED, INCLUDING BUT Non Limited TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO Issue SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR Whatsoever Merits, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
Source
View Source Code
- ";J
Post a Comment for "I Need to Reload H&r Block Tax Software Deluxe + State 2016 but Do Not Want to Pay for It Again"