Skip to content

Commit ac3afa2

Browse files
committed
Fix FFI::Axis
1 parent 20a4da8 commit ac3afa2

File tree

1 file changed

+20
-8
lines changed

1 file changed

+20
-8
lines changed

lib/gr.rb

Lines changed: 20 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -1192,7 +1192,7 @@ def drawaxis(option, axis)
11921192
def drawaxes(x_axis = nil, y_axis = nil, option = 1)
11931193
c_x = x_axis && __axis_to_c_axis(x_axis)
11941194
c_y = y_axis && __axis_to_c_axis(y_axis)
1195-
FFI.gr_drawaxes(c_x || 0, c_y || 0, option)
1195+
FFI.gr_drawaxes(c_x&.to_ptr, c_y&.to_ptr, option)
11961196
end
11971197

11981198
# Create axes in the current workspace and supply a custom function for
@@ -2550,6 +2550,8 @@ def ftoa(value, format_ref)
25502550
# Convert high-level GRAxis into low-level FFI::Axis
25512551
def __axis_to_c_axis(axis)
25522552
c_axis = FFI::Axis.malloc
2553+
# Keep references to allocated memory to prevent GC
2554+
memory_refs = []
25532555

25542556
c_axis.min_val = axis.min
25552557
c_axis.max_val = axis.max
@@ -2561,14 +2563,15 @@ def __axis_to_c_axis(axis)
25612563
# ticks
25622564
if axis.ticks && !axis.ticks.empty?
25632565
count = axis.ticks.size
2564-
mem = FFI::Tick.malloc(count)
2566+
mem = Fiddle::Pointer.malloc(FFI::Tick.size * count, Fiddle::RUBY_FREE)
2567+
memory_refs << mem
25652568
axis.ticks.each_with_index do |t, i|
2566-
tick = FFI::Tick.new(mem.to_ptr + i * FFI::Tick.size)
2569+
tick = FFI::Tick.new(mem + i * FFI::Tick.size)
25672570
tick.value = t.value
25682571
tick.is_major = t.is_major
25692572
end
25702573
c_axis.num_ticks = count
2571-
c_axis.ticks = mem.to_ptr
2574+
c_axis.ticks = mem.to_i
25722575
else
25732576
c_axis.num_ticks = 0
25742577
c_axis.ticks = 0
@@ -2579,15 +2582,21 @@ def __axis_to_c_axis(axis)
25792582
# tick labels
25802583
if axis.tick_labels && !axis.tick_labels.empty?
25812584
count = axis.tick_labels.size
2582-
mem = FFI::TickLabel.malloc(count)
2585+
mem = Fiddle::Pointer.malloc(FFI::TickLabel.size * count, Fiddle::RUBY_FREE)
2586+
memory_refs << mem
25832587
axis.tick_labels.each_with_index do |tl, i|
2584-
lbl = FFI::TickLabel.new(mem.to_ptr + i * FFI::TickLabel.size)
2588+
lbl = FFI::TickLabel.new(mem + i * FFI::TickLabel.size)
25852589
lbl.tick = tl.tick
2586-
lbl.label = Fiddle::Pointer[tl.label.to_s + "\0"]
2590+
# Allocate persistent memory for label string
2591+
label_str = tl.label.to_s + "\0"
2592+
label_ptr = Fiddle::Pointer.malloc(label_str.bytesize, Fiddle::RUBY_FREE)
2593+
memory_refs << label_ptr
2594+
label_ptr[0, label_str.bytesize] = label_str
2595+
lbl.label = label_ptr.to_i
25872596
lbl.width = tl.width
25882597
end
25892598
c_axis.num_tick_labels = count
2590-
c_axis.tick_labels = mem.to_ptr
2599+
c_axis.tick_labels = mem.to_i
25912600
else
25922601
c_axis.num_tick_labels = 0
25932602
c_axis.tick_labels = 0
@@ -2597,6 +2606,9 @@ def __axis_to_c_axis(axis)
25972606
c_axis.draw_axis_line = axis.draw_axis_line
25982607
c_axis.label_orientation = axis.label_orientation
25992608

2609+
# Store memory references in the axis object to prevent GC
2610+
c_axis.instance_variable_set(:@__memory_refs, memory_refs)
2611+
26002612
c_axis
26012613
end
26022614

0 commit comments

Comments
 (0)