Ring CFFI — Call C Libraries Directly from Ring

328 views
Skip to first unread message

Youssef Saeed

unread,
Apr 9, 2026, 3:26:01 PMApr 9
to The Ring Programming Language
Hello everyone,

I'm excited to announce the release of Ring CFFI — a powerful Foreign Function Interface library for the Ring programming language!

Built on libffi, Ring CFFI allows you to call C functions, manipulate C memory, work with structs/unions/enums, and pass Ring functions as C callbacks — all directly from Ring, without writing any C extension code.

Key Features:
  • Dynamic Library Loading: Load shared libraries (.so, .dll, .dylib) at runtime
  • C Function Calls: Call C functions directly from Ring with automatic type conversion
  • Pointer Operations: Pointer arithmetic, dereferencing, read/write access
  • Struct Support: Define and manipulate C structs with named field access
  • Union & Enum Support: Define and use C unions and enumerations
  • Callbacks: Pass Ring functions as C callbacks
  • Memory Management: Allocate and manage C memory directly
  • C String Handling: Seamless conversion between Ring and C strings
  • Cross-Platform: Works on Windows, Linux, macOS, and FreeBSD
  • High-Level OOP API: Clean FFI class with intuitive method names
Code Example:

Calling C functions from Ring is straightforward:

load "cffi.ring"

new FFI("libc.so.6") { # or msvcrt.dll on Windows
oPrintf = varFunc("printf", "int", ["string"])
varcall(oPrintf, ["Hello from Ring! Value: %d", 42])
}

You can also define and use C structs:

load "cffi.ring"

new FFI {
# Define a Point struct
point = defineStruct("Point", [
:x = "int",
:y = "int"
])

# Allocate and set fields
pPoint = structNew(point)
ptrSet(fieldPtr(pPoint, point, :x), "int", 10)
ptrSet(fieldPtr(pPoint, point, :y), "int", 20)

# Read fields
? "x = " + ptrGet(field(pPoint, point, :x), "int") # 10
? "y = " + ptrGet(field(pPoint, point, :y), "int") # 20
}

Installation

Install easily via RingPM:

ringpm install ring-cffi from ysdragon

Learn MoreNote: Ring CFFI is currently in beta. The API may change as the library evolves. Your testing and feedback are especially valuable at this stage!

Contributions are welcome!

Have ideas or found a bug? Please open an issue or submit a pull request on GitHub.

Your feedback is greatly appreciated!

Hope you find Ring CFFI useful!

Best regards,
Youssef

Mahmoud Fayed

unread,
Apr 9, 2026, 4:21:13 PMApr 9
to The Ring Programming Language
Hello Youssef

This is a very useful and important extension

Thanks for the development & sharing :D

Greetings,
Mahmoud

Bert Mariani

unread,
Apr 9, 2026, 4:52:54 PMApr 9
to The Ring Programming Language
Hello Youssef the Dragon

This is Tremendous with a Capital "T"
This will add some Fire Breathing performance to our Code !!

Best Regards
Bert Mariani

Youssef Saeed

unread,
Apr 9, 2026, 4:59:45 PMApr 9
to The Ring Programming Language
Hello Mahmoud,

Thank you very much for your kind words!

Best regards,
Youssef

Youssef Saeed

unread,
Apr 9, 2026, 5:11:01 PMApr 9
to The Ring Programming Language
Hello Bert,

Thank you for the "Tremendous" response! I love the "Fire Breathing" analogy—unlocking that level of performance seamlessly is exactly what I was aiming for with Ring CFFI.

Please feel free to share your feedback or any "fire" you create once you have the chance to try it out!

Best regards,
Youssef

Mahmoud Fayed

unread,
Apr 10, 2026, 7:24:00 AMApr 10
to The Ring Programming Language
Hello Youssef

You are welcome :D

Greetings,
Mahmoud

Mansour Ayouni

unread,
Apr 10, 2026, 8:04:34 AMApr 10
to Mahmoud Fayed, The Ring Programming Language
Hello Youssef,

I tested all the 23 test examples and they all work.

Is this output correct (I'm on Windows):
image.png

All the best,
Mansour

--

---
You received this message because you are subscribed to the Google Groups "The Ring Programming Language" group.
To unsubscribe from this group and stop receiving emails from it, send an email to ring-lang+...@googlegroups.com.
To view this discussion visit https://groups.google.com/d/msgid/ring-lang/1079bff2-0c78-4e9b-81c0-a12bd693664en%40googlegroups.com.

Youssef Saeed

unread,
Apr 10, 2026, 10:06:34 AMApr 10
to The Ring Programming Language
Hello Mansour,

Thank you for the feedback and for testing all 23 examples!

The output you're seeing (Parsed 0 definitions) was indeed a bug in the C Definition Parser (cffi_cdef). It has been fixed in the latest commit.

Please run:
  1. ringpm remove ring-cffi
  2. ringpm install ring-cffi
Then test example 13 again — it should now correctly report the number of parsed definitions.

Best regards,
Youssef

Bert Mariani

unread,
Apr 22, 2026, 4:51:00 PMApr 22
to The Ring Programming Language
Hello Youssef, Mahmoud  et ALL

Attached: combo for CFFI
     Queens-N.ring
     nqueens_solver.c

423 X Faster than pure Ring version

===========================================
Results:  CFFI Version
C:\MyStuff\AA-Queens-CFFI>ring.exe Queens-N.ring
Enter value of n : 12
Counting N-Queens solutions for n = 12 ...
Total solutions : 14200
End   millisec  : 2792
Start millisec  : 2695
Total millisec  : 97
Total seconds   : 0.10

===========================
Results: Ring code version

Enter value of n : 12
Possible placements are :

End   millisec: 44639
Start millisec: 3617
Total millisec: 41022
Total Seconds : 41.02
Exiting of the program...
Enter to Exit :


// ===========================================
// SETUP (one-time):
//   1. ringpm install ring-cffi from ysdragon   (already done)
//   2. Compile the C solver DLL in this same folder:
//        A.  gcc -O2 -shared -o nqueens.dll nqueens_solver.c
//        --------------------------------------------------------
//        B.  Use Visual Studio 2026 - 64 Bit
//
// The full working setup for anyone to replicate:
// # 1. Install ring-cffi
//   ringpm install ring-cffi from ysdragon
//
// # 2. Set up MSVC (64-bit)
//   call C:\ring\language\build\locatevc.bat x64
//
// # 3. Create the export definition
//   echo EXPORTS > nqueens.def
//   echo nqueens_count >> nqueens.def
//
// # 4. Compile the DLL
//   cl /O2 /LD nqueens_solver.c /Fe:nqueens.dll /link /DEF:nqueens.def
//
// # 5. Run
//   ring.exe Queens-N.ring
//==========================================

FILES generated
 nqueens.def
 nqueens.dll
 nqueens.exp
 nqueens.lib
 nqueens_solver.c
 nqueens_solver.obj
 Queens-N.ring

=============================

Regards
Bert Marini

nqueens_solver.c
Queens-N.ring

Mahmoud Fayed

unread,
Apr 22, 2026, 5:15:52 PMApr 22
to The Ring Programming Language
Hello Bert

Thanks for sharing

>> "Results:  CFFI Version"

This version is not attached, please attach it.

Greetings,
Mahmoud

Bert Mariani

unread,
Apr 22, 2026, 5:40:33 PMApr 22
to The Ring Programming Language
Sorry this is the CFFI version

Attached
     Queens-N.ring         (71 lines )
     nqueens_solver.c   (59 lines )

================================
================================

// Queens-N.ring  (ring-cffi accelerated version)
// Bert Mariani with Claude AI assistance
// 2026-04-22
//
// The hot N-Queens backtracking logic runs entirely in C via ring-cffi.
// Ring handles user I/O and timing only.
//
// ---------------------------------------------------------------

// SETUP (one-time):
//   1. ringpm install ring-cffi from ysdragon   (already done)
//   2. Compile the C solver DLL in this same folder:
//        A.  gcc -O2 -shared -o nqueens.dll nqueens_solver.c
//        --------------------------------------------------------
//        B.  Use Visual Studio 2026 - 64 Bit
//
// The full working setup for anyone to replicate:
// # 1. Install ring-cffi
// ringpm install ring-cffi from ysdragon
//
// # 2. Set up MSVC (64-bit)
//   call C:\ring\language\build\locatevc.bat x64
//
// # 3. Create the export definition
//   echo EXPORTS > nqueens.def
//   echo nqueens_count >> nqueens.def
//
// # 4. Compile the DLL
//   cl /O2 /LD nqueens_solver.c /Fe:nqueens.dll /link /DEF:nqueens.def
//
// # 5. Run
//   ring.exe Queens-N.ring
//==========================================

load "cffi.ring"

// --------------- load the shared C library ----------------------
oFfi = new FFI("nqueens.dll")

// Wrap the one C function we need:
//   long nqueens_count(int n)
oNQueens = oFfi.cFunc("nqueens_count", "int", ["int"])

// --------------- user input -------------------------------------
See "Enter value of n : "
Give n
n = 0 + n

See "Counting N-Queens solutions for n = " + n + " ..." + nl

// --------------- timed solve via C FFI --------------------------
start_t = clock()

    nSolutions = oFfi.invoke(oNQueens, [n])   // runs in compiled C

end_t   = clock()
total_t = end_t - start_t

// --------------- results ----------------------------------------
See nl
See "Total solutions : " + nSolutions + nl
See nl
See "End   millisec  : " + end_t   + nl
See "Start millisec  : " + start_t + nl
See "Total millisec  : " + total_t + nl

timeF = total_t / ClocksPerSecond()
See "Total seconds   : " + timeF   + nl

See nl + "Exiting of the program..." + nl
See "Enter to Exit : "
Give m

=====================================
=====================================
=====================================

/*
 * nqueens_solver.c
 * Fast N-Queens solver written in C.
 * Compile as a shared library for use with ring-cffi.
 *
 * Linux/macOS:
 *   gcc -O2 -shared -fPIC -o libnqueens.so nqueens_solver.c
 * Windows:
 *   gcc -O2 -shared -o nqueens.dll nqueens_solver.c
 */

#include <stdlib.h>
#include <string.h>

static int  *col;        /* column of queen in row i       */
static long  solution_count;

/* Inline safe absolute-value to avoid math.h dependency */
static inline int iabs(int v) { return v < 0 ? -v : v; }

/* Returns 1 if placing a queen at column i in row k is safe */
static int place(int k, int i) {
    int j;
    for (j = 0; j < k; j++) {
        if (col[j] == i || iabs(col[j] - i) == iabs(j - k))
            return 0;
    }
    return 1;
}

/* Recursive backtracking solver (0-based rows) */
static void solve(int k, int n) {
    int i;
    for (i = 0; i < n; i++) {
        if (place(k, i)) {
            col[k] = i;
            if (k == n - 1)
                solution_count++;
            else
                solve(k + 1, n);
        }
    }
}

/*
 * nqueens_count(n)
 *   Returns the total number of solutions for an n×n board.
 *   Exported for ring-cffi to call directly.
 */
long nqueens_count(int n) {
    if (n <= 0) return 0;
    col = (int *)malloc(n * sizeof(int));
    if (!col) return -1;
    solution_count = 0;
    solve(0, n);
    free(col);
    col = NULL;
    return solution_count;
}

============================
============================
============================
Queens-N.ring
nqueens_solver.c

Mahmoud Fayed

unread,
Apr 22, 2026, 5:44:11 PMApr 22
to The Ring Programming Language
Hello Bert

Thank you very much for sharing :D
This is a beautiful example about using C code and RingCFFI

By the way, attached: Fast N-Queens using Bitmask Backtracking
Written 100% in Ring and finish execution in around 1 second for (n=12)

Enter N: 12
Total solutions: 14200
Time (ms): 1123
Time (sec): 1.12

Time for other values

Enter N: 13
Total solutions: 73712
Time (ms): 6171
Time (sec): 6.17

Enter N: 14
Total solutions: 365596
Time (ms): 36016
Time (sec): 36.02

Greetings,
Mahmoud
nqueens_bitmask_backtracking.ring

Youssef Saeed

unread,
Apr 22, 2026, 8:08:20 PMApr 22
to The Ring Programming Language
Hello Bert,

Thank you so much for putting this fantastic example together!

A 423x speedup is an incredible real-world demonstration of what RingCFFI was designed for. I truly appreciate you creating such a clear and powerful benchmark.

Best regards,
Youssef

Youssef Saeed

unread,
Apr 22, 2026, 8:09:03 PMApr 22
to The Ring Programming Language
Hello Mahmoud,

Thank you for sharing your bitmask implementation!

Best regards,
Youssef

Mahmoud Fayed

unread,
Apr 22, 2026, 8:29:28 PMApr 22
to The Ring Programming Language
Hello Youssef

You are welcome :D

Greetings,
Mahmoud

Bert Mariani

unread,
Apr 23, 2026, 10:51:56 AMApr 23
to The Ring Programming Language
Hello Youssef, Mahmoud et ALL

The Bit Mask solution is quicker than the Back Tracker
Would you believe 5860 X faster than the Ring-Original

Attached
     Queens-N.ring         -- no change
     nqueens_solver.c    -- Bit Mask version

CFFI Bit Mask:                   7 msec   5860 X      160 X
CFFI Back Tracker:         97 msec     423 X        14 X   
Ring-Bit Mask:            1123 msec       36 X          1 X
Ring-Original         :  41022 msec          1 X

==============================
C:\MyStuff\AA-Queens-CFFI>ring.exe Queens-N.ring
Enter value of n : 12
Counting N-Queens solutions for n = 12 ...
Total solutions : 14200
End   millisec  : 3025
Start millisec  : 3018
Total millisec  : 7         <<<===
Total seconds   : 0.01

Exiting of the program...

==============================
Different Approach

___________________Old (backtracking)___________________New (bitmask)

Conflict check   Loop over all previous queens       Zero — bitmasks do it instantly
Memory   malloc array of columns       None — 3 integers on the stack
Operations per step   O(k) comparisons       2 bitwise ops (&, ~)
Expected speedup   baseline      ~3–5× faster

============================
============================
// Queens-N.ring  (ring-cffi accelerated version)
//  nqueens_solver.c  -  Bitmask backtracking N-Queens solver

#ifdef _MSC_VER
  #define EXPORT __declspec(dllexport)
#else
  #define EXPORT
#endif

static long solution_count;

/*
 * backtrack(colMask, diag1, diag2, all)
 *   Direct C translation of the Ring bitmask backtrack() function.
 */
static void backtrack(unsigned int colMask,
                      unsigned int diag1,
                      unsigned int diag2,
                      unsigned int all)
{
    unsigned int free_bits, bit;

    /* colMask == all means every column has a queen -> solution */
    if (colMask == all) {
        solution_count++;
        return;
    }

    /* available positions: free columns with no diagonal conflict */
    free_bits = all & ~(colMask | diag1 | diag2);

    while (free_bits) {
        /* pick the lowest set bit */
        bit = free_bits & (-(int)free_bits);

        /* remove this bit from free_bits */
        free_bits -= bit;

        /* recurse with updated column and diagonal masks */
        backtrack(
            colMask | bit,
            (diag1  | bit) << 1,
            (diag2  | bit) >> 1,
            all
        );
    }
}

/*
 * nqueens_count(n)
 *   Returns the total number of solutions for an n x n board.
 *   Called from Ring via ring-cffi.
 */
EXPORT long nqueens_count(int n)
{
    unsigned int all;

    if (n <= 0 || n > 31) return 0;

    all = (1u << n) - 1u;   /* n bits set, same as Ring: (1 << n) - 1 */

    solution_count = 0;
    backtrack(0, 0, 0, all);

    return solution_count;
}


=============================

Regards
Bert Mariani
Queens-N.ring
nqueens_solver.c

Mahmoud Fayed

unread,
Apr 23, 2026, 11:00:55 AMApr 23
to The Ring Programming Language
Hello Bert

>> "The Bit Mask solution is quicker than the Back Tracker"
>> "Would you believe 5860 X faster than the Ring-Original"

Thanks for sharing the updated code & benchmarks

Greetings,
Mahmoud

Robin

unread,
Apr 26, 2026, 8:52:05 AMApr 26
to The Ring Programming Language
Hi everyone,

I have a question about extending Ring.

When should I use CFFI versus writing a native extension using the extension tutorial? In which situations is one preferred over the other?

Also, how do they compare in terms of performance? Is using a native extension significantly faster than CFFI, or is the difference usually negligible?

Thanks in advance for your guidance.

Ilir Liburn

unread,
Apr 26, 2026, 11:57:31 AMApr 26
to The Ring Programming Language
Hello Robin,

here is the simple answer from the AI which explains basics:

FFI (Foreign Function Interface) is the general term for the mechanism that allows any two different languages to talk to each other.
The "C" in CFFI specifically stands for C, because C is the "lingua franca" of computing. Most high-level languages (Python, Rust, Java, Go) don't talk to each other directly; they both speak "C" as a middle ground.
How the Translation Works (The "Bridge")
When you pass data from a high-level language (like Python or JavaScript) to a low-level language (like C or Rust), the translation happens via two main concepts:
1. Data Marshalling (The Packaging)
High-level languages use "heavy" objects. For example, a Python integer isn't just a number; it's a structure containing a reference count, type info, and size. C only understands "raw" bytes.
  • The Translation: The FFI layer extracts the raw value (e.g., 42) from the Python object and places it into a specific memory slot (like a 4-byte int) that the C function expects.
2. The Calling Convention (The Handshake)
Different languages have different rules for how to actually run a function (e.g., "Do I put the arguments in CPU registers or on the Stack?").
  • The Translation: The FFI acts as a traffic controller. It rearranges the arguments to match the Application Binary Interface (ABI) of the target language so the CPU doesn't crash when it jumps from one language's code to the other.
Why Lists don't just "become" Arrays
This is where the friction lies.
  • High-level List: Usually a dynamic collection of pointers scattered in memory.
  • Low-level Array: A single, contiguous block of memory.
To "translate" a list to an array, the FFI must loop through the list, extract every single value, and copy them into a brand-new contiguous block of memory. This is why it isn't "automatic"—it’s a performance-heavy operation, so FFI tools usually make you do it explicitly.
Greetings,
Ilir

Bert Mariani

unread,
Apr 26, 2026, 4:35:30 PMApr 26
to The Ring Programming Language
Hello Robin, Mahmoud, Illir, Youssef et ALL

Using Ring API C Interface calls  -  Back-Track version
Attached:  Queens-N.ring
                   nqueens_solver-RingAPI.c

CFFI        Back Tracker:         97  msec    1 X   <<<  CFFI interface
Ring-API Back Track :         298   msec   3 X   <<<   Ring API C interface

---------------------------
Previous comparisons
CFFI Bit Mask:                   7 msec   5860 X      160 X
CFFI Back Tracker:         97 msec     423 X        14 X   
Ring-Bit Mask:            1123 msec       36 X          1 X
Ring-Original         :  41022 msec          1 X
------------------------------


=======================================
BATCH FILE to Run

cls

call C:\ring\language\build\locatevc.bat x64
cl /c /DEBUG nqueens_solver-RingAPI.c -I"C:\ring\language\include"
link /DEBUG nqueens_solver-RingAPI.obj C:\ring\lib\ring.lib /DLL /OUT:nqueens_ext.dll
del nqueens_solver-RingAPI.obj
=====================================


=========================================
c:\MyStuff\AA-Quuens-Ring-API>ring Queens-N.ring
Loading N-Queens native extension...


Enter value of n : 12

Counting N-Queens solutions for n = 12 ...

Total solutions : 14200

End   millisec  : 3500
Start millisec  : 3202
Total millisec  : 298    <<<<   Ring API C interface
Total seconds   : 0.30

Exiting the program...
---------------------------------------
Regards
Bert Mariani

Queens-N.ring
nqueens_solver-RingAPI.c

Ilir Liburn

unread,
Apr 26, 2026, 6:36:23 PMApr 26
to The Ring Programming Language
Hello Bert,

Ring C API version should be faster. On my Ring2C debug build + MSVC DLL release build:

Loading N-Queens native extension...

Enter value of n : 12

Counting N-Queens solutions for n = 12 ...

Total solutions : 14200

End   millisec  : 1305
Start millisec  : 1221
Total millisec  : 84
Total seconds   : 0.08

Exiting the program...

Anyway, I built faster DLL version which cuts total time to 30 millisec.

Greetings,
Ilir
nqueens_solver-RingAPI.c

Bert Mariani

unread,
Apr 26, 2026, 6:43:13 PMApr 26
to Ilir Liburn, The Ring Programming Language
Hello Ilir

Ok ... I see your faster speed with Ring 2C and Ring API

Now build the CFFI version I posted earlier to compare on your Ring 2C on your machine.

Regards 
Bert Mariani

Ilir Liburn

unread,
Apr 26, 2026, 6:54:51 PMApr 26
to The Ring Programming Language
Hello Bert,

I can't. I'm using Ring version 1.24 for development. CFFI requires 1.25, but decided to wait for 1.26 before merging it to Ring2C.

Once it is done later I can inform you about the results.

Greetings,
Ilir

Bert Mariani

unread,
Aug 13, 2026, 11:12:20 AM (10 days ago) Aug 13
to The Ring Programming Language
Hello Youssef

I have  C:\Ring   installed ( 64 bits)
I now also installed  C:\Ring32\ring   (32 bit)  -- need to use a 32bit DLL from C-code

c:\Ring32\ring\bin>    c:\Ring32\ring\bin\ringpm.exe install ring-cffi from ysdragon
Installing ring-cffi (master) ---> ring-cffi (1.0.0)
 - Note : Package Already Exists
c:\Ring32\ring\bin>

But if I look in  C:\Ring32\ring  it is not there.
Quick proof was the look at the samples/UsingCFFI
How do I install the CFFI library and sample on the Ring-32 ?

CFFI-32.PNG

Youssef Saeed

unread,
Aug 13, 2026, 12:16:25 PM (10 days ago) Aug 13
to The Ring Programming Language
Hello Bert,

The issue happens because ringpm relies on the PATH environment variable. Even when you run ringpm directly from the 32-bit folder, it still detects the 64-bit installation in your active environment path—which is why it reports that the package already exists.

You can fix this easily in your current Command Prompt session by prioritizing the 32-bit path first.

Option 1: Quick Fix (Current CMD Window)
Run these commands in your command prompt:

set PATH=C:\Ring32\ring\bin;%PATH%

ringpm install ring-cffi from ysdragon


Option 2: System-wide Fix
If you plan to use 32-bit as your main installation, update your Windows Environment Variables:
  1. Remove C:\ring\bin from your system PATH.
  2. Add C:\Ring32\ring\bin to your system PATH.
  3. Restart CMD and run the ringpm install command again.
Let me know if you need any further help!

Best regards,
Youssef

Bert Mariani

unread,
Aug 14, 2026, 3:18:19 PM (9 days ago) Aug 14
to The Ring Programming Language
Hello Youssef

Thanks for your suggestion.
Tried with "set Path",   Restart,  and Full Path command
Does not install the CFFI is the Ring32 directory.

Having both Rings on the same machine seems to be a problem where the libraries install
   Ring-64     C:\ring
   Ring-32     C\Ring32\ring

==================
c:\Ring32\ring>
c:\Ring32\ring>set PATH=C:\Ring32\ring\bin;%PATH%

c:\Ring32\ring>path
       PATH=C:\Ring32\ring\bin; .....  C:\Users\bert_\.bun\bin

c:\Ring32\ring>ringpm install ring-cffi from ysdragon

         Installing ring-cffi (master) ---> ring-cffi (1.0.0)
        - Note : Package Already Exists
c:\Ring32\ring>

===================
RESTART

===================
c:\Ring32\ring>
c:\Ring32\ring>ringpm install ring-cffi from ysdragon

         Installing ring-cffi (master) ---> ring-cffi (1.0.0)
         - Note : Package Already Exists

(Full Path Command)
c:\Ring32\ring>C:\Ring32\ring\bin\ringpm.exe    install ring-cffi from ysdragon

          Installing ring-cffi (master) ---> ring-cffi (1.0.0)
         - Note : Package Already Exists
c:\Ring32\ring>

=====================

Ring32-CFFI.png

Youssef Saeed

unread,
Aug 14, 2026, 3:40:33 PM (9 days ago) Aug 14
to The Ring Programming Language
Hello Bert,

You can try removing the package by running:

ringpm remove ring-cffi

Then reinstall it for the 32-bit version of Ring.

Best regards,
Youssef

Bert Mariani

unread,
Aug 14, 2026, 4:23:34 PM (9 days ago) Aug 14
to The Ring Programming Language
Hello Youssef

Here are the steps ..... gets more confused ...

c:\Ring32\ring>ringpm remove ring-cffi
Deleting ring-cffi
Removing files and folders
 ──────────────────────────
  Uninstalling Ring CFFI
 ──────────────────────────
 ❯ Removing load configuration…
 ✔ Load configuration removed
 ❯ Removing Ring2EXE configuration…
 ✔ Ring2EXE configuration removed
 ❯ Removing sample files…
 ✔ Samples removed
 ❯ Removing library files…
   → Removed from Ring bin directory
 ✔ Library files removed

 ✔ Ring CFFI uninstalled successfully!

 ℹ Removed: 4 component(s)
 ℹ Skipped: 0 component(s)

c:\Ring32\ring>

c:\Ring32\ring>C:\Ring32\ring\bin\ringpm.exe    install ring-cffi from ysdragon
Installing ring-cffi (master) ---> ring-cffi (1.0.0)
 - Note : Package Already Exists

c:\Ring32\ring>
======================================

c:\Ring32\ring>
c:\Ring32\ring>cd c:\ring

c:\ring>
c:\ring>  c:\ring\bin\ringpm remove ring-cffi
Error(3) : We don't have this package

c:\ring>

=======================


c:\Ring32\ring>C:\Ring32\ring\bin\ringpm.exe    install ring-cffi from ysdragon
Installing ring-cffi (master) ---> ring-cffi (1.0.0)
 - Note : Package Already Exists

c:\Ring32\ring>
==============================

samples/UsingCFFI  Not in Either Ring ??

CFI-Both-Ring.png

Message has been deleted

Youssef Saeed

unread,
Aug 15, 2026, 3:24:26 PM (8 days ago) Aug 15
to The Ring Programming Language
Hello Bert,

The problem: with both Rings on PATH, the package setup/remove scripts run
plain "ring", so Windows picks whichever ring.exe comes first in PATH (your
64-bit C:\ring). The package folder was downloaded into Ring32, but the DLL,
samples and load configuration were installed into the 64-bit tree. Your
later "ringpm remove" also resolved through PATH, so it uninstalled the
64-bit side. The leftover folder in Ring32 is why install keeps answering
"Package Already Exists" without doing anything.

To fix it:

1. Manually delete the leftover package folder from both installations:
     C:\Ring32\ring\tools\ringpm\packages\ring-cffi
     C:\ring\tools\ringpm\packages\ring-cffi   (if it still exists)

2. Open a NEW command prompt where only Ring32 is on PATH (remove C:\ring\bin
   temporarily, or be sure C:\Ring32\ring\bin comes before it).

3. Reinstall:

     C:\Ring32\ring\bin\ringpm.exe install ring-cffi from ysdragon

4. Verify you now have:
     C:\Ring32\ring\samples\UsingCFFI
     C:\Ring32\ring\bin\ring_cffi.dll
     C:\Ring32\ring\bin\load\cffi.ring

Note: your earlier remove operation stripped CFFI from C:\ring (64-bit).
If you want it back there too, put C:\ring\bin first on PATH and run
c:\ring\bin\ringpm install ring-cffi from ysdragon the same way.

Best regards,
Youssef

Bert Mariani

unread,
Aug 19, 2026, 10:32:26 AM (4 days ago) Aug 19
to The Ring Programming Language
Thanks Youssef

I started over again ...
C:\Ring  -- 64bit  installed CFFI  -- all good.

Installed C:\Ring32\ring
Modified system environmentals. See screen capture
       Path: C:\Ring32\ring\bin;  C:\ring\bin;
installed CFFI  -- all good

==========================
Attached:
   BCD-Add.ring
   bcd_lib.c            // creates bcd.dll  , handles 40 digits of BCD as configured

It MUST be run in Ring32. (details in script because  x86 instructions are 32 bits)
Either with Command line  or  Ring32 RingNotepad.exe
     //   Full Path in C:\Ring32\ring
     //      1. cd C:\MyStuff\AA-BCD
     //      2. C:\MyStuff\AA-BCD>C:\Ring32\ring\bin\ring.exe BCD-Add.ring

The CFFI portion in the Ring script that usses the current directory where the script lives.
       bcdDir = CurrentDir()
       if iswindows()
            oFfi = new FFI( bcdDir + "\bcd.dll")

// IMPORTANT - 32-BIT ONLY:
//   bcd_lib.c uses the x86 DAA instruction, which does not exist in 64-bit
//   mode
, so bcd.dll / libbcd.so MUST be built as 32-bit, and loaded by a
//   32-BIT Ring interpreter. This is
different from Queens-N.ring, which
//   targets 64-bit throughout - a 64-bit ring.exe cannot load a 32-bit DLL.
//   Ring distributes both 32-bit and 64-bit builds; use the 32-bit one for
//   this script.

SystemVariables.png

Ring32-RingNotepad.png

RESULTS:

Enter first number (up to 38 integer digits, 2 decimal places, e.g. 123.45): 123456.78
Enter second number (up to 38 integer digits, 2 decimal places, e.g. 123.45): 6789.45

Input 1 : 123456.78
Input 2 : 6789.45
Sum     : 130246.23

Add another? (Y/N):
bcd_lib.c
BCD-Add.ring

Youssef Saeed

unread,
Aug 19, 2026, 11:44:33 AM (4 days ago) Aug 19
to The Ring Programming Language
Hello Bert,

That's great news! Thanks for sharing the update and the sample.

Best regards,
Youssef
Reply all
Reply to author
Forward
0 new messages