How to Embed paxCompiler for Dynamic Scripting in C++ Builder
Adding a scripting engine to your C++ Builder application allows you to modify program logic without recompiling the entire executable. paxCompiler is an embeddable compiler for Object Pascal, C++, and JavaScript that runs entirely in memory and generates native machine code.
This guide provides a step-by-step walkthrough to integrate paxCompiler into an Embarcadero C++ Builder application. 1. Prerequisites and Installation
Before writing code, ensure you have the compiler components registered in your IDE.
Download the Package: Obtain the paxCompiler library files compatible with your version of C++ Builder.
Install the Components: Open the runtime and design-time packages (paxcomp.cbproj or .dpk) in C++ Builder, compile them, and click Install.
Verify Installation: Ensure TpaxCompiler and TpaxProgram appear in your Component Palette.
Library Paths: Add the source directory of paxCompiler to your project’s Include Path and Library Path under Project Options. 2. Setting Up the Components
You can drop the components directly onto a TForm or instantiate them dynamically in code. This example uses code-based instantiation for flexibility. Include the necessary header files in your main unit:
#include Use code with caution. 3. Writing the Integration Code
The compilation process involves binding an instance of TpaxCompiler to a TpaxProgram container, compiling the source string, and executing the binary result. Here is a complete, minimal implementation:
void __fastcall ExecuteScript() { // 1. Create the compiler and program instances std::unique_ptr Use code with caution. 4. Exposing Host Functions to the Script
A script engine is only useful if it can interact with your main application. You must register host functions so the script can call them. Step A: Define the Host Function
Define a global function or a static class method in your host C++ application.
// Host function to be called by the script void HostLog(System::String message) { // Assuming you want to print to a Memo component Form1->MemoLog->Lines->Add(“Script Output: ” + message); } Use code with caution. Step B: Register the Function with paxCompiler
Before calling Compile(), register the function signature and pointer.
// Registering the host function signature compiler->RegisterFunction(“void HostLog(string message)”, (void)&HostLog); Use code with caution. Step C: Call the Function Inside the Script The compiled script can now call HostLog natively:
String scriptCode = “int Main() { ” “ HostLog(“Data processed successfully.”); “ ” return 0; “ “} “; Use code with caution. 5. Performance and Memory Considerations
Native Speed: Unlike interpreted languages (like standard Lua or Python scripts), paxCompiler compiles scripts directly to machine code vectors. Execution speed matches natively compiled C++ code.
Memory Management: Ensure you free TpaxProgram instances when they are no longer needed. If you run scripts inside a tight loop, look into reusing the same TpaxProgram instance and calling program->Reset() instead of reallocating memory.
Thread Safety: TpaxCompiler is not thread-safe by default. If your C++ Builder app handles multi-threaded scripting, instantiate a separate compiler and program pair for each background thread. If you want, tell me:
Which C++ Builder version (e.g., 11 Alexandria, 12 Athens) you are using
Which scripting language (Pascal, C++, or JavaScript) your users will write in
If you need to pass complex objects/structs between the app and the script
I can provide specialized boilerplate code or troubleshooting steps for your exact setup.
Leave a Reply