Reputation: 1392
For example, this code won't compile
def double
x * x
end
lib LibC
# Error
def double
x * x
end
end
I know that we can use module, but we can't have the same LibC name as both module and lib
lib LibC
end
module LibC
def double
x * x
end
end
Is there any solution for this problem?
Upvotes: 0
Views: 103
Reputation: 4857
Why is this a problem for you? :)
lib
defines a binding to an external library. Technically it does so by defining function signatures of external symbols that the linker will resolve. Additionally it allows the definition of structs with C ABI semantics, enums for mapping a series of constants used in an external library interface into a useful grouping and aliases to make it easier to map Crystal types to C types in a binding definition.
When binding a library, this lowlevel lib
definition should never be the end result for the user of your binding! Instead you should define at least a thin wrapper transforming the external API into a more idiomatic Crystal version.
So say we're writing a binding to the fictional libsaucepan you would start out with a lib
definition, maybe like this:
@[Link("saucepan")]
lib LibSaucepan
alias Pan = Void*
fun aquire : Pan
fun add_water(pan : Pan, ml : LibC::Int)
fun cook(pan : Pan)
fun is_done(pan : Pan) : LibC::Int
end
You wouldn't stop here, but maybe create a class that wraps the API:
class Saucepan
def initialize
@pan = LibSaucepan.aquire
end
def add_water(ml : Int)
LibSaucepan.add_water(@pan, LibC::Int.new(ml))
end
def done?
LibSaucepan.is_done(@pan) == 1
end
def cook
LibSaucepan.cook(@pan)
until done?
sleep 1
end
end
def heat_water(ml : Int)
add_water(ml)
cook
end
end
This wrapper is where you would put any helper methods :)
Upvotes: 4