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