uia 0.0.4 → 0.0.5

Sign up to get free protection for your applications and to get access to all the features.
Files changed (90) hide show
  1. data/.rspec +1 -0
  2. data/ChangeLog +11 -0
  3. data/README.md +18 -1
  4. data/Rakefile +6 -1
  5. data/ext/UiaDll/UIA.Helper/Element.cs +52 -32
  6. data/ext/UiaDll/UiaDll.Test/AssemblyInfo.cpp +40 -0
  7. data/ext/UiaDll/UiaDll.Test/ElementInformationTest.cpp +89 -0
  8. data/ext/UiaDll/UiaDll.Test/ElementStub.h +59 -0
  9. data/ext/UiaDll/UiaDll.Test/ElementsTest.cpp +22 -0
  10. data/ext/UiaDll/UiaDll.Test/MemoryLeakDetector.h +47 -0
  11. data/ext/UiaDll/UiaDll.Test/ReadMe.txt +35 -0
  12. data/ext/UiaDll/UiaDll.Test/StringHelperTest.cpp +14 -0
  13. data/ext/UiaDll/UiaDll.Test/UiaDll.Test.cpp +16 -0
  14. data/ext/UiaDll/UiaDll.Test/UiaDll.Test.vcxproj +127 -0
  15. data/ext/UiaDll/UiaDll.Test/UiaDll.Test.vcxproj.filters +67 -0
  16. data/ext/UiaDll/UiaDll.Test/app.ico +0 -0
  17. data/ext/UiaDll/UiaDll.Test/app.rc +0 -0
  18. data/ext/UiaDll/UiaDll.Test/gmock/include/gmock/gmock-actions.h +1078 -0
  19. data/ext/UiaDll/UiaDll.Test/gmock/include/gmock/gmock-cardinalities.h +147 -0
  20. data/ext/UiaDll/UiaDll.Test/gmock/include/gmock/gmock-generated-actions.h +2415 -0
  21. data/ext/UiaDll/UiaDll.Test/gmock/include/gmock/gmock-generated-actions.h.pump +821 -0
  22. data/ext/UiaDll/UiaDll.Test/gmock/include/gmock/gmock-generated-function-mockers.h +991 -0
  23. data/ext/UiaDll/UiaDll.Test/gmock/include/gmock/gmock-generated-function-mockers.h.pump +265 -0
  24. data/ext/UiaDll/UiaDll.Test/gmock/include/gmock/gmock-generated-matchers.h +2190 -0
  25. data/ext/UiaDll/UiaDll.Test/gmock/include/gmock/gmock-generated-matchers.h.pump +674 -0
  26. data/ext/UiaDll/UiaDll.Test/gmock/include/gmock/gmock-generated-nice-strict.h +397 -0
  27. data/ext/UiaDll/UiaDll.Test/gmock/include/gmock/gmock-generated-nice-strict.h.pump +161 -0
  28. data/ext/UiaDll/UiaDll.Test/gmock/include/gmock/gmock-matchers.h +3986 -0
  29. data/ext/UiaDll/UiaDll.Test/gmock/include/gmock/gmock-more-actions.h +233 -0
  30. data/ext/UiaDll/UiaDll.Test/gmock/include/gmock/gmock-more-matchers.h +58 -0
  31. data/ext/UiaDll/UiaDll.Test/gmock/include/gmock/gmock-spec-builders.h +1791 -0
  32. data/ext/UiaDll/UiaDll.Test/gmock/include/gmock/gmock.h +94 -0
  33. data/ext/UiaDll/UiaDll.Test/gmock/include/gmock/internal/gmock-generated-internal-utils.h +279 -0
  34. data/ext/UiaDll/UiaDll.Test/gmock/include/gmock/internal/gmock-generated-internal-utils.h.pump +136 -0
  35. data/ext/UiaDll/UiaDll.Test/gmock/include/gmock/internal/gmock-internal-utils.h +498 -0
  36. data/ext/UiaDll/UiaDll.Test/gmock/include/gmock/internal/gmock-port.h +78 -0
  37. data/ext/UiaDll/UiaDll.Test/gmock/lib/gmock.lib +0 -0
  38. data/ext/UiaDll/UiaDll.Test/gmock/lib/gmockd.lib +0 -0
  39. data/ext/UiaDll/UiaDll.Test/gtest/include/gtest/gtest-death-test.h +294 -0
  40. data/ext/UiaDll/UiaDll.Test/gtest/include/gtest/gtest-message.h +250 -0
  41. data/ext/UiaDll/UiaDll.Test/gtest/include/gtest/gtest-param-test.h +1421 -0
  42. data/ext/UiaDll/UiaDll.Test/gtest/include/gtest/gtest-param-test.h.pump +487 -0
  43. data/ext/UiaDll/UiaDll.Test/gtest/include/gtest/gtest-printers.h +855 -0
  44. data/ext/UiaDll/UiaDll.Test/gtest/include/gtest/gtest-spi.h +232 -0
  45. data/ext/UiaDll/UiaDll.Test/gtest/include/gtest/gtest-test-part.h +179 -0
  46. data/ext/UiaDll/UiaDll.Test/gtest/include/gtest/gtest-typed-test.h +259 -0
  47. data/ext/UiaDll/UiaDll.Test/gtest/include/gtest/gtest.h +2291 -0
  48. data/ext/UiaDll/UiaDll.Test/gtest/include/gtest/gtest_pred_impl.h +358 -0
  49. data/ext/UiaDll/UiaDll.Test/gtest/include/gtest/gtest_prod.h +58 -0
  50. data/ext/UiaDll/UiaDll.Test/gtest/include/gtest/internal/gtest-death-test-internal.h +319 -0
  51. data/ext/UiaDll/UiaDll.Test/gtest/include/gtest/internal/gtest-filepath.h +206 -0
  52. data/ext/UiaDll/UiaDll.Test/gtest/include/gtest/internal/gtest-internal.h +1158 -0
  53. data/ext/UiaDll/UiaDll.Test/gtest/include/gtest/internal/gtest-linked_ptr.h +233 -0
  54. data/ext/UiaDll/UiaDll.Test/gtest/include/gtest/internal/gtest-param-util-generated.h +5143 -0
  55. data/ext/UiaDll/UiaDll.Test/gtest/include/gtest/internal/gtest-param-util-generated.h.pump +301 -0
  56. data/ext/UiaDll/UiaDll.Test/gtest/include/gtest/internal/gtest-param-util.h +619 -0
  57. data/ext/UiaDll/UiaDll.Test/gtest/include/gtest/internal/gtest-port.h +1947 -0
  58. data/ext/UiaDll/UiaDll.Test/gtest/include/gtest/internal/gtest-string.h +167 -0
  59. data/ext/UiaDll/UiaDll.Test/gtest/include/gtest/internal/gtest-tuple.h +1012 -0
  60. data/ext/UiaDll/UiaDll.Test/gtest/include/gtest/internal/gtest-tuple.h.pump +339 -0
  61. data/ext/UiaDll/UiaDll.Test/gtest/include/gtest/internal/gtest-type-util.h +3331 -0
  62. data/ext/UiaDll/UiaDll.Test/gtest/include/gtest/internal/gtest-type-util.h.pump +297 -0
  63. data/ext/UiaDll/UiaDll.Test/gtest/lib/gtest.lib +0 -0
  64. data/ext/UiaDll/UiaDll.Test/gtest/lib/gtestd.lib +0 -0
  65. data/ext/UiaDll/UiaDll.Test/resource.h +3 -0
  66. data/ext/UiaDll/UiaDll.Test/stdafx.cpp +7 -0
  67. data/ext/UiaDll/UiaDll.Test/stdafx.h +7 -0
  68. data/ext/UiaDll/UiaDll.sln +15 -0
  69. data/ext/UiaDll/UiaDll/ArrayHelper.h +20 -2
  70. data/ext/UiaDll/UiaDll/ElementMethods.cpp +18 -0
  71. data/ext/UiaDll/UiaDll/ElementStructures.h +36 -24
  72. data/ext/UiaDll/UiaDll/StringHelper.h +16 -2
  73. data/ext/UiaDll/UiaDll/UiaDll.vcxproj +0 -2
  74. data/ext/UiaDll/UiaDll/UiaDll.vcxproj.filters +0 -6
  75. data/lib/uia.rb +23 -117
  76. data/lib/uia/element.rb +38 -0
  77. data/lib/uia/library.rb +60 -0
  78. data/lib/uia/library/constants.rb +85 -0
  79. data/lib/uia/library/structs.rb +85 -0
  80. data/lib/uia/version.rb +1 -1
  81. data/spec/app/FizzWare.NBuilder.dll +0 -0
  82. data/spec/app/UIA.Extensions.dll +0 -0
  83. data/spec/app/WindowsForms.exe +0 -0
  84. data/spec/spec_helper.rb +21 -0
  85. data/spec/uia/element_spec.rb +56 -0
  86. data/spec/uia_spec.rb +28 -0
  87. data/uia.gemspec +13 -10
  88. metadata +134 -8
  89. data/ext/UiaDll/UiaDll/ArrayHelper.cpp +0 -22
  90. data/ext/UiaDll/UiaDll/StringHelper.cpp +0 -17
@@ -5,7 +5,21 @@ using namespace System::Runtime::InteropServices;
5
5
  ref class StringHelper
6
6
  {
7
7
  public:
8
- static void CopyToUnmanagedString(String^ source, char* destination, const int destinationSize);
9
- static char* ToUnmanaged(String^ string);
8
+ static void CopyToUnmanagedString(String^ source, char* destination, const int destinationSize)
9
+ {
10
+ auto unmanagedString = Marshal::StringToHGlobalAnsi(source);
11
+ strncpy_s(destination, destinationSize, (const char*)(void*)unmanagedString, _TRUNCATE);
12
+ Marshal::FreeHGlobal(unmanagedString);
13
+ }
14
+
15
+ static char* ToUnmanaged(String^ source)
16
+ {
17
+ if( nullptr == source ) return NULL;
18
+
19
+ const int numberOfBytes = source->Length + 1;
20
+ auto unmanagedString = new char[numberOfBytes];
21
+ CopyToUnmanagedString(source, unmanagedString, numberOfBytes);
22
+ return unmanagedString;
23
+ }
10
24
  };
11
25
 
@@ -83,7 +83,6 @@
83
83
  <ClInclude Include="StringHelper.h" />
84
84
  </ItemGroup>
85
85
  <ItemGroup>
86
- <ClCompile Include="ArrayHelper.cpp" />
87
86
  <ClCompile Include="AssemblyInfo.cpp" />
88
87
  <ClCompile Include="DynamicAssemblyResolver.cpp" />
89
88
  <ClCompile Include="ElementMethods.cpp" />
@@ -91,7 +90,6 @@
91
90
  <PrecompiledHeader Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">Create</PrecompiledHeader>
92
91
  <PrecompiledHeader Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">Create</PrecompiledHeader>
93
92
  </ClCompile>
94
- <ClCompile Include="StringHelper.cpp" />
95
93
  <ClCompile Include="UiaDll.cpp" />
96
94
  </ItemGroup>
97
95
  <ItemGroup>
@@ -47,11 +47,5 @@
47
47
  <ClCompile Include="ElementMethods.cpp">
48
48
  <Filter>Source Files</Filter>
49
49
  </ClCompile>
50
- <ClCompile Include="StringHelper.cpp">
51
- <Filter>Source Files</Filter>
52
- </ClCompile>
53
- <ClCompile Include="ArrayHelper.cpp">
54
- <Filter>Source Files</Filter>
55
- </ClCompile>
56
50
  </ItemGroup>
57
51
  </Project>
data/lib/uia.rb CHANGED
@@ -1,117 +1,23 @@
1
- require 'uia/version'
2
- require 'ffi'
3
-
4
- module Uia
5
- extend FFI::Library
6
-
7
- module ElementLayout
8
- def self.included(base)
9
- base.class_eval do
10
- layout :handle, :int,
11
- :runtime_id, :pointer,
12
- :number_of_ids, :int,
13
- :name, :string
14
-
15
- def handle
16
- self[:handle]
17
- end
18
-
19
- def runtime_id
20
- self[:runtime_id].read_array_of_int(number_of_ids)
21
- end
22
-
23
- def number_of_ids
24
- self[:number_of_ids]
25
- end
26
-
27
- def children(type=nil)
28
- elements = (type && Uia.children_of_type(self, type)) || Uia.children(self)
29
- elements.children
30
- end
31
-
32
- def name
33
- self[:name]
34
- end
35
-
36
- def click
37
- Uia.click(self)
38
- end
39
- end
40
- end
41
- end
42
-
43
- class ElementStruct < FFI::ManagedStruct
44
- include ElementLayout
45
-
46
- def self.release(pointer)
47
- Uia.release_element(pointer)
48
- end
49
- end
50
-
51
- class ElementCast < FFI::Struct
52
- include ElementLayout
53
- end
54
-
55
- class ElementChildrenStruct < FFI::ManagedStruct
56
- layout :length, :int,
57
- :items, :pointer
58
-
59
- def children
60
- @children ||= self[:length].times.collect do |i|
61
- ElementCast.new(self[:items] + i * ElementCast.size)
62
- end
63
- end
64
-
65
- def self.release(pointer)
66
- Uia.release_elements(pointer)
67
- end
68
- end
69
-
70
- def self.uia_directory
71
- File.dirname(__FILE__) + '/../ext/UiaDll/Release'
72
- end
73
-
74
- ffi_lib File.join(uia_directory, 'UiaDll.dll')
75
- ffi_convention :stdcall
76
-
77
- attach_function :init, :initialize, [:string], :void
78
- init(uia_directory)
79
-
80
- PropertyId = enum(:is_selection_item, 0)
81
-
82
-
83
- def self.attach_throwable_function(name_alias, name, arg_types, return_type)
84
- attach_function name, arg_types + [:pointer, :int], return_type
85
- define_singleton_method(name_alias) do |*args|
86
- can_throw(name, *args)
87
- end
88
- end
89
-
90
- # cleanup
91
- attach_function :release_element, :Element_Release, [:pointer], :void
92
- attach_function :release_elements, :Element_ReleaseMany, [:pointer], :void
93
-
94
- # finding elements
95
- attach_throwable_function :find_by_id, :Element_FindById, [:string], ElementStruct.by_ref
96
- attach_throwable_function :find_by_handle, :Element_FindByHandle, [:int], ElementStruct.by_ref
97
- attach_function :Element_FindByRuntimeId, [:pointer, :int, :pointer, :int], ElementStruct.by_ref
98
-
99
- # element methods
100
- attach_throwable_function :children, :Element_Children, [:pointer], ElementChildrenStruct.by_ref
101
- attach_throwable_function :children_of_type, :Element_ChildrenOfType, [:pointer, PropertyId], ElementChildrenStruct.by_ref
102
- attach_throwable_function :click, :Element_Click, [:pointer], :void
103
-
104
- def self.find_by_runtime_id(id)
105
- p = FFI::MemoryPointer.new :int, id.count
106
- p.write_array_of_int(id)
107
- can_throw(:Element_FindByRuntimeId, p, id.count)
108
- end
109
-
110
- def self.can_throw(method, *args)
111
- string_buffer = FFI::MemoryPointer.new :char, 1024
112
- result = send method, *(args << string_buffer << 1024)
113
- error_info = string_buffer.read_string
114
- raise error_info unless error_info.empty?
115
- result
116
- end
117
- end
1
+ require 'uia/version'
2
+ require 'uia/library'
3
+ require 'uia/element'
4
+ require 'uia/library/constants'
5
+
6
+ module Uia
7
+ class BadLocator < StandardError; end
8
+
9
+ def find_element(how)
10
+ case
11
+ when how[:id]
12
+ Element.new Library.find_by_id(how[:id])
13
+ when how[:pid]
14
+ Element.new Library.find_by_pid(how[:pid])
15
+ when how[:runtime_id]
16
+ Element.new Library.find_by_runtime_id(how[:runtime_id])
17
+ when how[:handle]
18
+ Element.new Library.find_by_handle(how[:handle])
19
+ else
20
+ raise BadLocator, "#{how} is not a valid locator"
21
+ end
22
+ end
23
+ end
@@ -0,0 +1,38 @@
1
+ module Uia
2
+ class Element
3
+ def initialize(element)
4
+ @element = element
5
+ @default = lambda { [:unknown] }
6
+ end
7
+
8
+ def control_type
9
+ Library::Constants::ControlTypes.find(@default) { |_, v| v == control_type_id }.first
10
+ end
11
+
12
+ def patterns
13
+ pattern_ids.map do |id|
14
+ Library::Constants::Patterns.find(@default) { |_, v| v == id }.first
15
+ end
16
+ end
17
+
18
+ def children
19
+ @element.children.map { |c| Element.new c }
20
+ end
21
+
22
+ def descendants
23
+ @element.descendants.map { |c| Element.new c }
24
+ end
25
+
26
+ def click
27
+ Library.click(@element)
28
+ true
29
+ end
30
+
31
+ def method_missing(meth, *args, &block)
32
+ if @element.respond_to? meth
33
+ return @element.send(meth, *args, &block)
34
+ end
35
+ super
36
+ end
37
+ end
38
+ end
@@ -0,0 +1,60 @@
1
+ require 'uia/library/structs'
2
+ require 'ffi'
3
+
4
+ module Uia
5
+ module Library
6
+ extend FFI::Library
7
+
8
+ PropertyId = enum(:is_selection_item, 0)
9
+
10
+ def self.uia_directory
11
+ File.dirname(__FILE__) + '/../../ext/UiaDll/Release'
12
+ end
13
+
14
+ ffi_lib File.join(uia_directory, 'UiaDll.dll')
15
+ ffi_convention :stdcall
16
+
17
+ attach_function :init, :initialize, [:string], :void
18
+ init(uia_directory)
19
+
20
+ def self.attach_throwable_function(name_alias, name, arg_types, return_type)
21
+ attach_function name, arg_types + [:pointer, :int], return_type
22
+ define_singleton_method(name_alias) do |*args|
23
+ can_throw(name, *args)
24
+ end
25
+ end
26
+
27
+ # cleanup
28
+ attach_function :release_element, :Element_Release, [:pointer], :void
29
+ attach_function :release_elements, :Element_ReleaseMany, [:pointer], :void
30
+
31
+ # finding elements
32
+ attach_throwable_function :find_by_id, :Element_FindById, [:string], ElementStruct.by_ref
33
+ attach_throwable_function :find_by_pid, :Element_FindByProcessId, [:int], ElementStruct.by_ref
34
+ attach_throwable_function :find_by_handle, :Element_FindByHandle, [:int], ElementStruct.by_ref
35
+ attach_function :Element_FindByRuntimeId, [:pointer, :int, :pointer, :int], ElementStruct.by_ref
36
+
37
+ # element methods
38
+ attach_throwable_function :children, :Element_Children, [:pointer], ElementChildrenStruct.by_ref
39
+ attach_throwable_function :children_of_type, :Element_ChildrenOfType, [:pointer, PropertyId], ElementChildrenStruct.by_ref
40
+ attach_throwable_function :descendants, :Element_Descendants, [:pointer], ElementChildrenStruct.by_ref
41
+ attach_throwable_function :click, :Element_Click, [:pointer], :void
42
+
43
+ def self.find_by_runtime_id(id)
44
+ p = FFI::MemoryPointer.new :int, id.count
45
+ p.write_array_of_int(id)
46
+ can_throw(:Element_FindByRuntimeId, p, id.count)
47
+ end
48
+
49
+ def self.can_throw(method, *args)
50
+ string_buffer = FFI::MemoryPointer.new :char, 1024
51
+ result = send method, *(args << string_buffer << 1024)
52
+ error_info = string_buffer.read_string
53
+ raise error_info unless error_info.empty?
54
+ result
55
+ end
56
+
57
+ rescue LoadError => e
58
+ raise LoadError, 'You must install the Visual Studio 2012 C++ Runtime Environment to use the Uia gem (http://www.microsoft.com/en-us/download/details.aspx?id=30679)'
59
+ end
60
+ end
@@ -0,0 +1,85 @@
1
+ module Uia
2
+ module Library
3
+ module Constants
4
+ Patterns = {
5
+ :annotation => 10023,
6
+ :dock => 10011,
7
+ :drag => 10030,
8
+ :drop_target => 10031,
9
+ :expand_collapse => 10005,
10
+ :grid_item => 10007,
11
+ :grid => 10006,
12
+ :invoke => 10000,
13
+ :item_container => 10019,
14
+ :legacy_i_accessible => 10018,
15
+ :multiple_view => 10008,
16
+ :object_model => 10022,
17
+ :range_value => 10003,
18
+ :scroll_item => 10017,
19
+ :scroll => 10004,
20
+ :selection_item => 10010,
21
+ :selection => 10001,
22
+ :spreadsheet => 10026,
23
+ :spreadsheet_item => 10027,
24
+ :styles => 10025,
25
+ :synchronized_input => 10021,
26
+ :table_item => 10013,
27
+ :table => 10012,
28
+ :text_child => 10029,
29
+ :text_edit => 10032,
30
+ :text => 10014,
31
+ :text_pattern2 => 10024,
32
+ :toggle => 10015,
33
+ :transform => 10016,
34
+ :transform_pattern2 => 10028,
35
+ :value => 10002,
36
+ :virtualized_item => 10020,
37
+ :window => 10009
38
+ }
39
+
40
+ ControlTypes = {
41
+ :app_bar => 50040,
42
+ :button => 50000,
43
+ :calendar => 50001,
44
+ :check_box => 50002,
45
+ :combo_box => 50003,
46
+ :custom => 50025,
47
+ :data_grid => 50028,
48
+ :data_item => 50029,
49
+ :document => 50030,
50
+ :edit => 50004,
51
+ :group => 50026,
52
+ :header => 50034,
53
+ :header_item => 50035,
54
+ :hyperlink => 50005,
55
+ :image => 50006,
56
+ :list => 50008,
57
+ :list_item => 50007,
58
+ :menu_bar => 50010,
59
+ :menu => 50009,
60
+ :menu_item => 50011,
61
+ :pane => 50033,
62
+ :progress_bar => 50012,
63
+ :radio_button => 50013,
64
+ :scroll_bar => 50014,
65
+ :semantic_zoom => 50039,
66
+ :separator => 50038,
67
+ :slider => 50015,
68
+ :spinner => 50016,
69
+ :split_button => 50031,
70
+ :status_bar => 50017,
71
+ :tab => 50018,
72
+ :tab_item => 50019,
73
+ :table => 50036,
74
+ :text => 50020,
75
+ :thumb => 50027,
76
+ :title_bar => 50037,
77
+ :tool_bar => 50021,
78
+ :tool_tip => 50022,
79
+ :tree => 50023,
80
+ :tree_item => 50024,
81
+ :window => 50032
82
+ }
83
+ end
84
+ end
85
+ end
@@ -0,0 +1,85 @@
1
+ require 'ffi'
2
+
3
+ module Uia
4
+ module Library
5
+ module ElementLayout
6
+ def self.included(base)
7
+ base.class_eval do
8
+ layout :handle, :int,
9
+ :runtime_id, :pointer,
10
+ :number_of_ids, :int,
11
+ :name, :string,
12
+ :control_type_id, :int,
13
+ :patterns, :pointer,
14
+ :patterns_length, :int,
15
+ :id, :string
16
+
17
+ def id
18
+ self[:id]
19
+ end
20
+
21
+ def name
22
+ self[:name]
23
+ end
24
+
25
+ def handle
26
+ self[:handle]
27
+ end
28
+
29
+ def runtime_id
30
+ self[:runtime_id].read_array_of_int(number_of_ids)
31
+ end
32
+
33
+ def control_type_id
34
+ self[:control_type_id]
35
+ end
36
+
37
+ def pattern_ids
38
+ self[:patterns].read_array_of_int(self[:patterns_length])
39
+ end
40
+
41
+ def children(type=nil)
42
+ elements = (type && Library.children_of_type(self, type)) || Library.children(self)
43
+ elements.children
44
+ end
45
+
46
+ def descendants
47
+ Library.descendants(self).children
48
+ end
49
+
50
+ private
51
+ def number_of_ids
52
+ self[:number_of_ids]
53
+ end
54
+ end
55
+ end
56
+ end
57
+
58
+ class ElementStruct < FFI::ManagedStruct
59
+ include ElementLayout
60
+
61
+ def self.release(pointer)
62
+ Library.release_element(pointer)
63
+ end
64
+ end
65
+
66
+ class ElementCast < FFI::Struct
67
+ include ElementLayout
68
+ end
69
+
70
+ class ElementChildrenStruct < FFI::ManagedStruct
71
+ layout :length, :int,
72
+ :items, :pointer
73
+
74
+ def children
75
+ @children ||= self[:length].times.collect do |i|
76
+ ElementCast.new(self[:items] + i * ElementCast.size)
77
+ end
78
+ end
79
+
80
+ def self.release(pointer)
81
+ Library.release_elements(pointer)
82
+ end
83
+ end
84
+ end
85
+ end