Calling a FreeBasic Shared Library from Python w/ Arrays

Post your FreeBASIC source, examples, tips and tricks here. Please don’t post code without including an explanation.
Post Reply
octonion
Posts: 1
Joined: Mar 17, 2018 17:58

Calling a FreeBasic Shared Library from Python w/ Arrays

Post by octonion »

Here's an example for how to call a FreeBasic shared library from Python with an array parameter. It's similar to how you call Go from Python, but FreeBasic's array structure is a bit more complicated than a Go slice.

All of my code is also in my Github repo (https://github.com/octonion/puzzles/tre ... thon-basic.

FreeBasic partitions.bas:

Code: Select all

Function partitions alias "partitions" (cards() as integer, subtotal as integer) as integer
    dim i as integer
    dim m as integer
    dim total as integer
    m = 0
    ' Hit
    for i = 0 to 9
        if (cards(i)>0) then
            total = subtotal+i+1
            if (total < 21) then
                ' Stand
                m += 1
                ' Hit again
		cards(i) -= 1
                m = m+partitions(cards(), total)
                cards(i) += 1
            elseif (total=21) then
                ' Stand; hit again is an automatic bust
                m += 1
	    end if
        end if
    next
    return m
end function
Python outcomes2.py:

Code: Select all

#!/usr/bin/env python

from ctypes import *
import os

#typedef struct _FBARRAYDIM {
#        size_t elements;
#        ssize_t lbound;
#        ssize_t ubound;
#} FBARRAYDIM;

#typedef struct _FBARRAY {
#        void           *data;        /* ptr + diff, must be at ofs 0! */
#        void           *ptr;
#        size_t          size;
#        size_t          element_len;
#        size_t          dimensions;
#        FBARRAYDIM      dimTB[1];    /* dimtb[dimensions] */
#} FBARRAY;

class FBArray(Structure):
    _fields_ = [("data", POINTER(c_size_t)),
                ("ptr", POINTER(c_size_t)),
                ("size", c_size_t),
                ("element_len", c_size_t),
                ("dimensions", c_size_t),
                ("elements", c_size_t),
                ("lbound", c_ssize_t),
                ("ubound", c_ssize_t)]

lib = cdll.LoadLibrary(os.path.abspath("libpartitions.so"))
lib.partitions.argtypes = [POINTER(FBArray), c_size_t]
lib.partitions.restype = c_int

deck = ([4]*9)
deck.append(16)

d = 0

for i in xrange(10):
    # Dealer showing
    deck[i] -= 1
    p = 0
    for j in xrange(10):
        deck[j] -= 1
        pdeck = (c_size_t*len(deck))(*deck)
        cards = FBArray(pdeck,pdeck,
                        sizeof(pdeck),
                        sizeof(c_size_t),
                        1,
                        len(deck),
                        0,len(deck)-1)
        p += lib.partitions(cards, c_size_t(j+1))
        deck[j] += 1
    print('Dealer showing ', i,' partitions =',p)
    d += p
    deck[i] += 1

print('Total partitions =',d)
Compiled and executed via:

Code: Select all

fbc -O 3 -dylib -pic partitions.bas
python outcomes2.py
Output:

Code: Select all

('Dealer showing ', 0, ' partitions =', 417334)
('Dealer showing ', 1, ' partitions =', 560954)
('Dealer showing ', 2, ' partitions =', 658854)
('Dealer showing ', 3, ' partitions =', 679464)
('Dealer showing ', 4, ' partitions =', 680299)
('Dealer showing ', 5, ' partitions =', 680305)
('Dealer showing ', 6, ' partitions =', 680305)
('Dealer showing ', 7, ' partitions =', 680305)
('Dealer showing ', 8, ' partitions =', 680305)
('Dealer showing ', 9, ' partitions =', 680305)
('Total partitions =', 6398430)

real	0m0.045s
user	0m0.045s
sys	0m0.000s
Post Reply