C++ Wrapper
Overview
The C++ wrapper provides a header-only RAII class that wraps the C API. It automatically manages resource lifetime and provides a convenient object-oriented interface.
#include "gcode_api.hpp"The GCode class is non-copyable but movable, ensuring safe resource management.
Class Definition
class GCode {
public:
explicit GCode(const std::string& license_key); // Creates instance, throws on failure
~GCode(); // Destroys instance
GCode(const GCode&) = delete; // Non-copyable
GCode& operator=(const GCode&) = delete;
GCode(GCode&& other) noexcept; // Movable
GCode& operator=(GCode&& other) noexcept;
// Connection
int Connect(const std::string& ip);
void Disconnect();
bool IsConnected() const;
// Commands
int AddCommand(const std::string& cmd);
int AddFile(const std::string& path);
int GetQueueSize() const;
int ClearQueue();
// Execution
int Start();
int Stop();
int WaitForQueueEmpty(int timeout_ms = -1);
// Configuration
int ConfigureLinearAxis(char gcode_axis, char dmc_axis,
double counts_per_unit, double forward_limit = INFINITY);
int ConfigureSpindle(char dmc_axis, double counts_per_rev);
int ConfigureExtruder(char dmc_axis, double counts_per_user_unit);
// Callbacks (invoked on worker thread)
void SetOnError(GCodeErrorCallback cb, void* data = nullptr);
void SetOnStopped(GCodeEventCallback cb, void* data = nullptr);
void SetOnStarted(GCodeEventCallback cb, void* data = nullptr);
// Access underlying handle
GCodeHandle GetHandle() const;
};Constructor and Destructor
GCode(const std::string& license_key)
explicit GCode(const std::string& license_key);Creates a new GCode instance with the provided license key. Throws std::runtime_error if the license key is invalid or expired.
Parameters:
license_key- Your license key string (provided by Galil)
~GCode()
~GCode();Destroys the instance and releases all resources. Automatically disconnects if connected.
Connection Methods
Connect
int Connect(const std::string& ip);Connects to a Galil DMC controller at the specified IP address. Returns GCODE_OK on success, or an error code on failure.
Disconnect
void Disconnect();Disconnects from the controller. Safe to call even if not connected.
IsConnected
bool IsConnected() const;Returns true if connected to a controller, false otherwise.
Command Methods
AddCommand
int AddCommand(const std::string& cmd);Adds a single G-code command to the execution queue.
gcode.AddCommand("G1 X10 Y20 F100");AddFile
int AddFile(const std::string& path);Loads and adds all G-code commands from a file to the execution queue.
GetQueueSize
int GetQueueSize() const;Returns the number of commands currently waiting in the queue.
ClearQueue
int ClearQueue();Clears all pending commands from the queue. Does not affect the currently executing command.
Execution Methods
Start
int Start();Starts or resumes processing the queued G-code commands on a background worker thread. Idempotent: calling when already running is a no-op. If paused (M0/M1 or error), resumes from where it left off.
Stop
int Stop();Stops processing G-code commands. The current command will complete before stopping. Call Start() to resume processing.
WaitForQueueEmpty
int WaitForQueueEmpty(int timeout_ms = -1);Blocks until all queued commands have been processed.
Parameters:
timeout_ms- Maximum wait time in milliseconds. Default is -1 (infinite wait).
Returns:
GCODE_OKwhen queue is emptyGCODE_ERR_TIMEOUTif timeout expires
// Wait up to 30 seconds
int result = gcode.WaitForQueueEmpty(30000);
if (result == GCODE_ERR_TIMEOUT) {
// Handle timeout
}
// Or wait indefinitely
gcode.WaitForQueueEmpty();Configuration Methods
Note: Configuration methods must be called when the processor is not actively running. Calling these while processing returns GCODE_ERR_PROCESSING_ACTIVE.
ConfigureLinearAxis
int ConfigureLinearAxis(
char gcode_axis,
char dmc_axis,
double counts_per_unit,
double forward_limit = INFINITY
);Configures the mapping between a G-code axis letter and a physical DMC controller axis.
Parameters:
gcode_axis- G-code axis letter ('X', 'Y', 'Z', etc.)dmc_axis- DMC axis letter ('A' through 'H')counts_per_unit- Encoder counts per user unit (inch or mm)forward_limit- Maximum travel in user units. Default isINFINITY(no limit).
// Map G-code X to DMC axis A, 1000 counts/mm, 200mm limit
gcode.ConfigureLinearAxis('X', 'A', 1000.0, 200.0);
// Map G-code Y to DMC axis B, no limit
gcode.ConfigureLinearAxis('Y', 'B', 1000.0);ConfigureSpindle
int ConfigureSpindle(char dmc_axis, double counts_per_rev);Configures the DMC axis that controls the spindle.
Parameters:
dmc_axis- DMC axis letter ('A' through 'H')counts_per_rev- Encoder counts per spindle revolution
ConfigureExtruder
int ConfigureExtruder(char dmc_axis, double counts_per_user_unit);Configures the DMC axis that controls the extruder.
Parameters:
dmc_axis- DMC axis letter ('A' through 'H')counts_per_user_unit- Conversion factor from user units to controller counts
Callback Methods
See the Callbacks page for detailed documentation.
void SetOnError(GCodeErrorCallback cb, void* data = nullptr);
void SetOnStopped(GCodeEventCallback cb, void* data = nullptr);
void SetOnStarted(GCodeEventCallback cb, void* data = nullptr);Complete Example
#include "gcode_api.hpp"
#include <iostream>
void onError(int code, const char* cmd, void* data) {
std::cerr << "Error " << code << " on: " << cmd << std::endl;
}
int main() {
try {
GCode gcode("your-license-key-here");
// Set up callbacks
gcode.SetOnError(onError);
// Connect
if (gcode.Connect("192.168.1.100") != GCODE_OK) {
std::cerr << "Connection failed" << std::endl;
return 1;
}
std::cout << "Connected: " << gcode.IsConnected() << std::endl;
// Configure axes
gcode.ConfigureLinearAxis('X', 'A', 1000.0, 100.0);
gcode.ConfigureLinearAxis('Y', 'B', 1000.0, 100.0);
gcode.ConfigureLinearAxis('Z', 'C', 1000.0, 50.0);
// Configure spindle
gcode.ConfigureSpindle('D', 4000.0);
// Add commands
gcode.AddCommand("G90"); // Absolute positioning
gcode.AddCommand("G1 X10 Y10 F500"); // Move to (10, 10)
gcode.AddCommand("M3 S1000"); // Start spindle at 1000 RPM
gcode.AddCommand("G1 Z-5 F100"); // Plunge
gcode.AddCommand("G1 X50 Y50"); // Cut to (50, 50)
gcode.AddCommand("G1 Z10"); // Retract
gcode.AddCommand("M5"); // Stop spindle
std::cout << "Queue size: " << gcode.GetQueueSize() << std::endl;
// Execute
gcode.Start();
// Wait with 60 second timeout
int result = gcode.WaitForQueueEmpty(60000);
if (result == GCODE_ERR_TIMEOUT) {
std::cerr << "Execution timed out" << std::endl;
gcode.Stop();
}
std::cout << "Complete" << std::endl;
return 0;
}
catch (const std::exception& e) {
std::cerr << "Exception: " << e.what() << std::endl;
return 1;
}
}Visual Studio Project Setup
- Create a new Visual Studio C++ Console Application Project
- Right-click on your project in Solution Explorer and select "Properties"
- Under "C/C++" → "General" → "Additional Include Directories", add
$(GALIL_GCODES) - Under "Linker" → "General" → "Additional Library Directories", add
$(GALIL_GCODES) - Under "Linker" → "Input" → "Additional Dependencies", add:
gcode_apid.libfor Debug buildsgcode_api.libfor Release builds
Note: Replace the IP address with your actual controller's address. Make sure your device is powered on and accessible on the network before running.