Back to API Reference

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_OK when queue is empty
  • GCODE_ERR_TIMEOUT if 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 is INFINITY (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

  1. Create a new Visual Studio C++ Console Application Project
  2. Right-click on your project in Solution Explorer and select "Properties"
  3. Under "C/C++" → "General" → "Additional Include Directories", add $(GALIL_GCODES)
  4. Under "Linker" → "General" → "Additional Library Directories", add $(GALIL_GCODES)
  5. Under "Linker" → "Input" → "Additional Dependencies", add:
    • gcode_apid.lib for Debug builds
    • gcode_api.lib for 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.