struct-mappings v0.1.0
struct-mappings
Generate crystal classes mapping C structures.
Purpose
struct-mappings exposes useful macros that can be used to convert a C struct into a Crystal class and vice versa.
The inner representation of the data is a NamedTuple which is very convenient to use.
Utility
Conversion from & to a C structure could be useful in the following scenarios:
- Persisting data that would get freed otherwise when calling an external library.
 - Avoiding calling 
.valueon nested structure pointers. - C structs are arguably less convenient to use compared to named tuples.
 
Features
- Supports nested structures.
 - Automatically allocates & dereference structure pointers.
 - C structures containing array pointers can be converted to an array wrapper class.
 - Conversion can be customized.
 
Installation
- 
Add the dependency to your
shard.yml:dependencies: struct-mappings: github: elbywan/struct-mappings - 
Run
shards install 
Usage
Require
require "struct-mappings"
Minimal use case
# Include the Mappings module
include Mappings
# Define a dummy structure.
lib C
  struct Data
    int: LibC::Int
  end
end
# Map this structure to a crystal class.
struct_mapping Data, C::Data,
  int : Int32
# The class can be instantiated from a named tuple containing the fields…
data = Data.new({int: 10})
# or directly from the C structure.
data_from_c = Data.new(
  C::Data.new int: 10
)
# The two classes hold the same data.
pp data == data_from_c # => true
# And it can be converted back using the `to_unsafe` method.
pp data.to_unsafe # => C::Data(@int=10)
# For structures that represent arrays, it's also quite simple.
# Define a dummy array.
lib C
  struct DataArray
    data: Data*
    size: LibC::Int
  end
end
# Map the array to a crystal class.
# Generates a `DataArray` class which is a wrapper around
# an Array of `Data` classes, and mapping the `C::DataArray` struct.
struct_array_mapping DataArray, Data, C::DataArray
# Can be instantiated from a crystal array…
array_from_data = DataArray.new [
  Data.new({int: 10}),
  Data.new({int: 20}),
]
pp array_from_data # => [{int: 10}, {int: 20}]
# or a C structure representation.
array_from_c = DataArray.new C::DataArray.new(
  size: 2,
  data: [
    C::Data.new(int: 10),
    C::Data.new(int: 20),
  ].to_unsafe
)
pp array_from_c # => [{int: 10}, {int: 20}]
# The two classes hold the same data.
pp array_from_data == array_from_c # => true
# And it can be converted back using the `to_unsafe` method.
pp array_from_data.to_unsafe # => C::DataArray(@data=Pointer(C::Data)@0x10e1cfda0, @size=2)
Documentation
The exhaustive documentation is hosted here.
Contributing
- Fork it (https://github.com/your-github-user/struct-mappings/fork)
 - Create your feature branch (
git checkout -b my-new-feature) - Commit your changes (
git commit -am 'Add some feature') - Push to the branch (
git push origin my-new-feature) - Create a new Pull Request
 
Contributors
- elbywan - creator and maintainer
 
Repository
  struct-mappings
Owner
  
  Statistic
  - 1
 - 0
 - 0
 - 1
 - 0
 - almost 6 years ago
 - November 17, 2019
 
License
  MIT License
Links
  
  Synced at
  Tue, 04 Nov 2025 05:58:33 GMT
Languages