Repository URL to install this package:
|
Version:
1.9.14 ▾
|
#
# This file is part of ruby-ffi.
# For licensing, see LICENSE.SPECS
#
require File.expand_path(File.join(File.dirname(__FILE__), "spec_helper"))
describe "Library" do
describe ".enum_value" do
m = Module.new do
extend FFI::Library
enum :something, [:one, :two]
end
it "should return a value for a valid key" do
expect(m.enum_value(:one)).to eq(0)
expect(m.enum_value(:two)).to eq(1)
end
it "should return nil for an invalid key" do
expect(m.enum_value(:three)).to be nil
end
end
describe "#ffi_convention" do
it "defaults to :default" do
m = Module.new do
extend FFI::Library
end
expect(m.ffi_convention).to eq(:default)
end
it "should be settable" do
m = Module.new do
extend FFI::Library
end
expect(m.ffi_convention).to eq(:default)
m.ffi_convention :stdcall
expect(m.ffi_convention).to eq(:stdcall)
end
end
if FFI::Platform::OS =~ /windows|cygwin/ && FFI::Platform::ARCH == 'i386'
module LibTestStdcall
extend FFI::Library
ffi_lib TestLibrary::PATH
ffi_convention :stdcall
class StructUCDP < FFI::Struct
layout :a1, :uchar,
:a2, :double,
:a3, :pointer
end
attach_function :testStdcallManyParams, [ :pointer, :int8, :int16, :int32, :int64,
StructUCDP.by_value, StructUCDP.by_ref, :float, :double ], :void
end
it "adds stdcall decoration: testStdcallManyParams@64" do
s = LibTestStdcall::StructUCDP.new
po = FFI::MemoryPointer.new :long
LibTestStdcall.testStdcallManyParams po, 1, 2, 3, 4, s, s, 1.0, 2.0
end
end
describe "ffi_lib" do
it "empty name list should raise error" do
expect {
Module.new do |m|
m.extend FFI::Library
ffi_lib
end
}.to raise_error(LoadError)
end
end
unless RbConfig::CONFIG['target_os'] =~ /mswin|mingw/
it "attach_function with no library specified" do
expect {
Module.new do |m|
m.extend FFI::Library
attach_function :getpid, [ ], :uint
end
}.to raise_error
end
it "attach_function :getpid from this process" do
expect {
expect(Module.new do |m|
m.extend FFI::Library
ffi_lib FFI::Library::CURRENT_PROCESS
attach_function :getpid, [ ], :uint
end.getpid).to eq(Process.pid)
}.not_to raise_error
end
it "loads library using symbol" do
expect {
expect(Module.new do |m|
m.extend FFI::Library
ffi_lib :c
attach_function :getpid, [ ], :uint
end.getpid).to eq(Process.pid)
}.not_to raise_error
end
it "attach_function :getpid from [ 'c', 'libc.so.6'] " do
expect {
expect(Module.new do |m|
m.extend FFI::Library
ffi_lib [ 'c', 'libc.so.6' ]
attach_function :getpid, [ ], :uint
end.getpid).to eq(Process.pid)
}.not_to raise_error
end
it "attach_function :getpid from [ 'libc.so.6', 'c' ] " do
expect {
expect(Module.new do |m|
m.extend FFI::Library
ffi_lib [ 'libc.so.6', 'c' ]
attach_function :getpid, [ ], :uint
end.getpid).to eq(Process.pid)
}.not_to raise_error
end
it "attach_function :getpid from [ 'libfubar.so.0xdeadbeef', nil, 'c' ] " do
expect {
expect(Module.new do |m|
m.extend FFI::Library
ffi_lib [ 'libfubar.so.0xdeadbeef', nil, 'c' ]
attach_function :getpid, [ ], :uint
end.getpid).to eq(Process.pid)
}.not_to raise_error
end
it "attach_function :getpid from [ 'libfubar.so.0xdeadbeef' ] " do
expect {
expect(Module.new do |m|
m.extend FFI::Library
ffi_lib 'libfubar.so.0xdeadbeef'
attach_function :getpid, [ ], :uint
end.getpid).to eq(Process.pid)
}.to raise_error(LoadError)
end
it "attach_function :bool_return_true from [ File.expand_path(#{TestLibrary::PATH.inspect}) ]" do
mod = Module.new do |m|
m.extend FFI::Library
ffi_lib File.expand_path(TestLibrary::PATH)
attach_function :bool_return_true, [ ], :bool
end
expect(mod.bool_return_true).to be true
end
end
def gvar_lib(name, type)
Module.new do |m|
m.extend FFI::Library
ffi_lib TestLibrary::PATH
attach_variable :gvar, "gvar_#{name}", type
attach_function :get, "gvar_#{name}_get", [], type
attach_function :set, "gvar_#{name}_set", [ type ], :void
end
end
def gvar_test(name, type, val)
lib = gvar_lib(name, type)
lib.set(val)
expect(lib.gvar).to eq(val)
lib.set(0)
lib.gvar = val
expect(lib.get).to eq(val)
end
[ 0, 127, -128, -1 ].each do |i|
it ":char variable" do
gvar_test("s8", :char, i)
end
end
[ 0, 0x7f, 0x80, 0xff ].each do |i|
it ":uchar variable" do
gvar_test("u8", :uchar, i)
end
end
[ 0, 0x7fff, -0x8000, -1 ].each do |i|
it ":short variable" do
gvar_test("s16", :short, i)
end
end
[ 0, 0x7fff, 0x8000, 0xffff ].each do |i|
it ":ushort variable" do
gvar_test("u16", :ushort, i)
end
end
[ 0, 0x7fffffff, -0x80000000, -1 ].each do |i|
it ":int variable" do
gvar_test("s32", :int, i)
end
end
[ 0, 0x7fffffff, 0x80000000, 0xffffffff ].each do |i|
it ":uint variable" do
gvar_test("u32", :uint, i)
end
end
[ 0, 0x7fffffffffffffff, -0x8000000000000000, -1 ].each do |i|
it ":long_long variable" do
gvar_test("s64", :long_long, i)
end
end
[ 0, 0x7fffffffffffffff, 0x8000000000000000, 0xffffffffffffffff ].each do |i|
it ":ulong_long variable" do
gvar_test("u64", :ulong_long, i)
end
end
if FFI::Platform::LONG_SIZE == 32
[ 0, 0x7fffffff, -0x80000000, -1 ].each do |i|
it ":long variable" do
gvar_test("long", :long, i)
end
end
[ 0, 0x7fffffff, 0x80000000, 0xffffffff ].each do |i|
it ":ulong variable" do
gvar_test("ulong", :ulong, i)
end
end
else
[ 0, 0x7fffffffffffffff, -0x8000000000000000, -1 ].each do |i|
it ":long variable" do
gvar_test("long", :long, i)
end
end
[ 0, 0x7fffffffffffffff, 0x8000000000000000, 0xffffffffffffffff ].each do |i|
it ":ulong variable" do
gvar_test("ulong", :ulong, i)
end
end
end
it "Pointer variable" do
lib = gvar_lib("pointer", :pointer)
val = FFI::MemoryPointer.new :long
lib.set(val)
expect(lib.gvar).to eq(val)
lib.set(nil)
lib.gvar = val
expect(lib.get).to eq(val)
end
[ 0, 0x7fffffff, -0x80000000, -1 ].each do |i|
it "structure" do
class GlobalStruct < FFI::Struct
layout :data, :long
end
lib = Module.new do |m|
m.extend FFI::Library
ffi_lib TestLibrary::PATH
attach_variable :gvar, "gvar_gstruct", GlobalStruct
attach_function :get, "gvar_gstruct_get", [], GlobalStruct
attach_function :set, "gvar_gstruct_set", [ GlobalStruct ], :void
end
val = GlobalStruct.new
val[:data] = i
lib.set(val)
expect(lib.gvar[:data]).to eq(i)
val[:data] = 0
lib.gvar[:data] = i
val = GlobalStruct.new(lib.get)
expect(val[:data]).to eq(i)
end
end
end