Module: RdlLibrary
- Extended by:
- Fiddle::Importer
- Defined in:
- lib/majorsilence_reporting/report_native.rb
Overview
Ruby Fiddle wrapper for the rdlnative shared library.
Loads the Majorsilence Reporting engine in-process via Fiddle — no subprocess is spawned, no .NET runtime is required on the host.
Platform-specific library filenames:
Linux: librdlnative.so
macOS: librdlnative.dylib
Windows: rdlnative.dll
Usage:
require 'majorsilence_reporting/report_native'
lib = RdlLibrary.load('/path/to/librdlnative.so')
rpt = ReportNative.new(lib, '/path/to/report.rdl')
rpt.set_parameter('Country', 'Germany')
rpt.set_connection_string('Data Source=myserver.db')
# Export to a file
rpt.export('pdf', '/tmp/output.pdf')
# Export to bytes
data = rpt.export_to_memory('pdf')
Supported export types: "pdf", "csv", "xlsx", "xlsx_table", "xml", "rtf", "tif", "tifb", "html", "mht"
Class Method Summary collapse
-
.load(lib_path) ⇒ Object
Load the rdlnative shared library and initialize the engine.
- .rdl_last_error_str(fns) ⇒ Object
Class Method Details
.load(lib_path) ⇒ Object
Load the rdlnative shared library and initialize the engine. Returns a Hash of bound Fiddle::Function objects. Call this once per process before creating any ReportNative instances.
41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 |
# File 'lib/majorsilence_reporting/report_native.rb', line 41 def self.load(lib_path) lib_path = File.(lib_path) lib_dir = File.dirname(lib_path) # Tell the C# resolver where to find P/Invoke sibling libraries (libSkiaSharp.so, # libe_sqlite3.so, etc.) — must be set before rdl_init() is called. ENV['RDLNATIVE_LIB_DIR'] = lib_dir # Pre-load all shared libraries in the directory with RTLD_GLOBAL (Fiddle's # default). On .NET 10+, libSystem.Native.so and sibling P/Invoke targets are # shared libraries — they must be globally visible before rdlnative.so runs. ext = RUBY_PLATFORM =~ /darwin/ ? '*.dylib' : '*.so' Dir.glob(File.join(lib_dir, ext)).sort.each do |f| begin Fiddle.dlopen(f) rescue Fiddle::DLError; end end handle = Fiddle.dlopen(lib_path) fns = { rdl_init: Fiddle::Function.new( handle['rdl_init'], [], Fiddle::TYPE_INT ), rdl_report_open: Fiddle::Function.new( handle['rdl_report_open'], [Fiddle::TYPE_VOIDP, Fiddle::TYPE_VOIDP], Fiddle::TYPE_VOIDP ), rdl_report_set_param: Fiddle::Function.new( handle['rdl_report_set_param'], [Fiddle::TYPE_VOIDP, Fiddle::TYPE_VOIDP, Fiddle::TYPE_VOIDP], Fiddle::TYPE_INT ), rdl_dataset_set_field: Fiddle::Function.new( handle['rdl_dataset_set_field'], [Fiddle::TYPE_VOIDP, Fiddle::TYPE_VOIDP, Fiddle::TYPE_VOIDP, Fiddle::TYPE_VOIDP], Fiddle::TYPE_INT ), rdl_dataset_commit_row: Fiddle::Function.new( handle['rdl_dataset_commit_row'], [Fiddle::TYPE_VOIDP, Fiddle::TYPE_VOIDP], Fiddle::TYPE_INT ), rdl_report_render_file: Fiddle::Function.new( handle['rdl_report_render_file'], [Fiddle::TYPE_VOIDP, Fiddle::TYPE_VOIDP, Fiddle::TYPE_VOIDP], Fiddle::TYPE_INT ), rdl_free: Fiddle::Function.new( handle['rdl_free'], [Fiddle::TYPE_VOIDP], Fiddle::TYPE_VOID ), rdl_report_close: Fiddle::Function.new( handle['rdl_report_close'], [Fiddle::TYPE_VOIDP], Fiddle::TYPE_VOID ), rdl_last_error: Fiddle::Function.new( handle['rdl_last_error'], [], Fiddle::TYPE_VOIDP ), } ret = fns[:rdl_init].call raise "rdl_init failed: #{rdl_last_error_str(fns)}" unless ret.zero? fns end |
.rdl_last_error_str(fns) ⇒ Object
105 106 107 108 109 110 |
# File 'lib/majorsilence_reporting/report_native.rb', line 105 def self.rdl_last_error_str(fns) ptr = fns[:rdl_last_error].call return 'unknown error' if ptr.nil? || ptr.zero? Fiddle::Pointer.new(ptr).to_s end |