# CStruct Document

## Types in CStruct

### Supported primitive types in CStruct

signed types:
char int8 int16 int32 int64 float double
unsigend types:
uchar uint8 uint16 uint32 uint64

### C types to CStruct types(32-bit platform)

C types | CStruct types
--- | ---
char | char | int8
short | int16
int | int32
long | int32
unsigned char | uchar | uint8
unsigned short | uint16
unsigned int | uint32
unsigned long | uint32
float | float
double | double

## Options in CStruct

:endian
Yon can use options method to set the options of a sturct.
class Point < CStruct
options :endian=>:little # or :big
int32:x
int32:y
end
The :endian's default value is :little.Therefore the Point is can defined like this:
class Point < CStruct
int32:x
int32:y
end

## Methods in CStruct

CStruct provides several methods to get some infomation for a struct.

### ::size

Return a struct's size. It has an alias:__size__.

### ::endian

Return a struct's endian.

### #data

Return a instance's data buffer. It has an alias:__data__.

### #reset

Reset a instance's data buffer. It has an alias:__reset__.

### #<<

Assign to struct's instance.

### #to_cstr

If a member of the struct is char buffer(i.e. It's a C sytle string),it has to_cstr method that return a ruby string.
And,the member can be assigned by a ruby string.
See Examples:File IO for more information.
Sample Example:
p Point.size # 8
p Point.endian # :little
point = Point.new
point.x = 1
point.y = 2
p point.__data__ # "\x01\x00\x00\x00\x02\x00\x00\x00"
point.__reset__
p point.__data__ # "\x00\x00\x00\x00\x00\x00\x00\x00"

## Map C/C++ struct to Ruby

### Sample struct

C/C++ | Ruby
--- | ---
struct Point { int x; int y; }; | class Point < CStruct int32:x int32:y end

### Array member

C/C++ | Ruby
--- | ---
struct T { int element[8]; }; | class T < CStruct int32:elements,[8] end

### Struct member

C/C++ | Ruby
--- | ---
struct Point { int x; int y; }; struct Line { Point begin_point; Point end_point; }; | class Point < CStruct int32:x int32:y end class Line < CStruct Point:begin_point Point:end_point end

### Inner struct

C/C++ | Ruby
--- | ---
struct A { struct Inner { int v1; int v2; }; Inner inner; }; | class A < CStruct class Inner < CStruct int32 :v1 int32 :v2 end Inner :inner end

### Inner union

Named union is unsupported in CStruct.
Fortunately, anonymous union can take the place of it.See also: Anonymous union.

C/C++ | Ruby
--- | ---
struct U { union NumericType { int x; int y; }; NumericType value; }; | class U < CStruct union:value do int32:x int32:y end end

### Anonymous Struct

C/C++ | Ruby
--- | ---
struct Window { int style; struct{ int x; int y; }position; }; | class Window < CStruct int32:style struct :position do int32:x int32:y end end

### Anonymous union

C/C++ | Ruby
--- | ---
struct U { union{ int x; int y; } value; }; | class U < CStruct union:value do int32:x int32:y end end

### Namespace

C++ | Ruby
--- | ---
namespace NS1{ struct A { int handle; }; namespace NS2 { struct B { A a; }; } struct C { A a; NS2::B b; }; } | module NS1 class A < CStruct uint32:handle end module NS2 class B < CStruct A:a end end class C < CStruct A :a NS2_B :b end end

Meaning of the 'NS2_B' is NS2::B!

## Extend CStruct

### Open CStruct class

You can open CStruct class to define yourself types.
e.g.
class CStruct
class << self
alias uint32_t uint32
alias uint16_t uint16
end
end
class MyStrcut < CStruct
uint32_t:value
end

### Define a new types struct

It is a good idea to define a individual struct to wrap the types.Win32Struct is an example of this.Please read on.

## Win32Struct

### Win32Struct's source

class Win32Struct< CStruct
class << self
alias HANDLE uint32
alias HMODULE uint32
alias HINSTANCE uint32
alias HRGN uint32
alias HTASK uint32
alias HKEY uint32
alias HDESK uint32
alias HMF uint32
alias HEMF uint32
alias HRSRC uint32
......
......
end
end

### Using Win32Struct

In order to use Win32Struct,you must require it.

    require 'win32struct'

By using Win32Struct,we can easily define a struct that exist in Windows SDK.
For example:
class PROCESSENTRY32 < Win32Struct
DWORD :dwSize
DWORD :cntUsage
DWORD :th32ProcessID
DWORD :th32DefaultHeapID
DWORD :th32ModuleID
DWORD :cntThreads
DWORD :th32ParentProcessID
LONG :pcPriClassBase
DWORD :dwFlags
CHAR :szExeFile,[260]
end
See Examples:Show All Process,GlobalMemoryStatus for more information.

## CStruct and Win32Utils The Win32Utils project is powerful and convenient! Win32Utils can be used together with CStruct(Win32Struct). The Win32's example of theCStruct that has used windows-pr gem. It is worth mentioning that the win32-api 1.4.6 gem is not available on ruby 1.9.x. You can compile it yourself use DevKit. And replace the win32-api-1.4.6-x86-mingw32's api.so.

Back to Home