@@ -31,12 +31,12 @@ First, you should install LLVM clang.
3131See the LLVM Clang instructions at http://apt.llvm.org/ or use your distribution's packages.
3232
3333Either use an installer relevant for your OS (APT, downloads, etc..) to install libclang
34- ```
34+ ``` sh
3535$ sudo apt install libclang1-11
3636```
3737
3838or you can use the LLVM install script that installs the whole llvm toolkit
39- ```
39+ ``` sh
4040 wget https://apt.llvm.org/llvm.sh && chmod +x llvm.sh
4141 # then install llvm version 16
4242 ./llvm.sh 16
@@ -65,7 +65,7 @@ But if you encounter a version compatibility issue, you might have to fix the pr
6565using one of the following solutions:
6666
67671 . set the CLANG_LIBRARY_PATH environmental variable to the clang library file or path
68- ```
68+ ``` sh
6969$ export CLANG_LIBRARY_PATH=/lib/x86_64-linux-gnu/libclang-11.so.1
7070$ clang2py --version
7171versions - clang2py:2.3.3 clang:11.1.0 python-clang:11.0
@@ -81,132 +81,134 @@ versions - clang2py:2.3.3 clang:11.1.0 python-clang:11.0
8181## Usage
8282### Use ctypeslib2 as a Library in your own python code
8383
84-
85- import ctypeslib
86- py_module = ctypeslib.translate('''int i = 12;''')
87- print(py_module.i) # Prints 12
88-
89- py_module2 = ctypeslib.translate('''struct coordinates { int i ; int y; };''')
90- print(py_module2.struct_coordinates) # <class 'struct_coordinates'>
91- print(py_module2.struct_coordinates(1,2)) # <struct_coordinates object at 0xabcde12345>
92-
93- # input files, output file
94- py_module3 = ctypeslib.translate_files(['mytest.c'], outfile=open('mytest.py', 'w'))
95- print(open('mytest.py').read())
96-
97- # input files, output code
98- py_module4 = ctypeslib.translate_files(['mytest.c'])
99- print(open('mytest.py').read())
100-
101- # input files, output code, with clang options, like cross-platform
102- from ctypeslib.codegen import config
103- cfg = config.CodegenConfig()
104- cfg.clang_opts.extend(['-target', 'arm-gnu-linux'])
105- py_module5 = ctypeslib.translate_files(['mytest.c'], cfg=cfg)
106- print(open('mytest.py').read())
107-
84+ ``` py
85+ import ctypeslib
86+ py_module = ctypeslib.translate(''' int i = 12;''' )
87+ print (py_module.i) # Prints 12
88+
89+ py_module2 = ctypeslib.translate(''' struct coordinates { int i ; int y; };''' )
90+ print (py_module2.struct_coordinates) # <class 'struct_coordinates'>
91+ print (py_module2.struct_coordinates(1 ,2 )) # <struct_coordinates object at 0xabcde12345>
92+
93+ # input files, output file
94+ py_module3 = ctypeslib.translate_files([' mytest.c' ], outfile = open (' mytest.py' , ' w' ))
95+ print (open (' mytest.py' ).read())
96+
97+ # input files, output code
98+ py_module4 = ctypeslib.translate_files([' mytest.c' ])
99+ print (open (' mytest.py' ).read())
100+
101+ # input files, output code, with clang options, like cross-platform
102+ from ctypeslib.codegen import config
103+ cfg = config.CodegenConfig()
104+ cfg.clang_opts.extend([' -target' , ' arm-gnu-linux' ])
105+ py_module5 = ctypeslib.translate_files([' mytest.c' ], cfg = cfg)
106+ print (open (' mytest.py' ).read())
107+ ```
108108
109109Look at ` test/test_api.py ` for more advanced Library usage
110110
111111
112112### Use ctypeslib2 on the command line
113113
114114Source file:
115-
116- $ cat t.c
117- struct my_bitfield {
115+ ``` c
116+ // t.c
117+ struct my_bitfield {
118118 long a:3;
119119 long b:4;
120120 unsigned long long c:3;
121121 unsigned long long d:3;
122122 long f:2;
123- };
123+ };
124+ ```
124125
125126Run c-to-python script:
126127
127128 clang2py t.c
128129
129130Output:
130-
131- # -*- coding: utf-8 -*-
132- #
133- # TARGET arch is: []
134- # WORD_SIZE is: 8
135- # POINTER_SIZE is: 8
136- # LONGDOUBLE_SIZE is: 16
137- #
138- import ctypes
139-
140- class struct_my_bitfield(ctypes.Structure):
141- _pack_ = True # source:False
142- _fields_ = [
143- ('a', ctypes.c_int64, 3),
144- ('b', ctypes.c_int64, 4),
145- ('c', ctypes.c_int64, 3),
146- ('d', ctypes.c_int64, 3),
147- ('f', ctypes.c_int64, 2),
148- ('PADDING_0', ctypes.c_int64, 49)]
149-
150- __all__ = \
151- ['struct_my_bitfield']
131+ ``` py
132+ # -*- coding: utf-8 -*-
133+ #
134+ # TARGET arch is: []
135+ # WORD_SIZE is: 8
136+ # POINTER_SIZE is: 8
137+ # LONGDOUBLE_SIZE is: 16
138+ #
139+ import ctypes
140+
141+ class struct_my_bitfield (ctypes .Structure ):
142+ _pack_ = True # source:False
143+ _fields_ = [
144+ (' a' , ctypes.c_int64, 3 ),
145+ (' b' , ctypes.c_int64, 4 ),
146+ (' c' , ctypes.c_int64, 3 ),
147+ (' d' , ctypes.c_int64, 3 ),
148+ (' f' , ctypes.c_int64, 2 ),
149+ (' PADDING_0' , ctypes.c_int64, 49 )]
150+
151+ __all__ = \
152+ [' struct_my_bitfield' ]
153+ ```
152154
153155### use ctypeslib with additional clang arguments:
154156
155157Source file:
158+ ``` c
159+ // test-stdbool.c
160+ #include < stdbool.h>
156161
157- $ cat test-stdbool.c
158- #include <stdbool.h>
159-
160- typedef struct s_foo {
162+ typedef struct s_foo {
161163 bool bar1;
162164 bool bar2;
163165 bool bar3;
164- } foo;
165-
166+ } foo;
167+ ```
166168
167169Run c-to-python script (with any relevant include folder):
168170
169171 clang2py --clang-args="-I/usr/include/clang/4.0/include" test-stdbool.c
170172
171173Output:
172-
173- # -*- coding: utf-8 -*-
174- #
175- # TARGET arch is: ['-I/usr/include/clang/4.0/include']
176- # WORD_SIZE is: 8
177- # POINTER_SIZE is: 8
178- # LONGDOUBLE_SIZE is: 16
179- #
180- import ctypes
181-
182- class struct_s_foo(ctypes.Structure):
183- _pack_ = True # source:False
184- _fields_ = [
185- ('bar1', ctypes.c_bool),
186- ('bar2', ctypes.c_bool),
187- ('bar3', ctypes.c_bool),]
188-
189- foo = struct_s_foo
190- __all__ = ['struct_s_foo', 'foo']
191-
174+ ``` py
175+ # -*- coding: utf-8 -*-
176+ #
177+ # TARGET arch is: ['-I/usr/include/clang/4.0/include']
178+ # WORD_SIZE is: 8
179+ # POINTER_SIZE is: 8
180+ # LONGDOUBLE_SIZE is: 16
181+ #
182+ import ctypes
183+
184+ class struct_s_foo (ctypes .Structure ):
185+ _pack_ = True # source:False
186+ _fields_ = [
187+ (' bar1' , ctypes.c_bool),
188+ (' bar2' , ctypes.c_bool),
189+ (' bar3' , ctypes.c_bool),]
190+
191+ foo = struct_s_foo
192+ __all__ = [' struct_s_foo' , ' foo' ]
193+ ```
192194
193195## _ pack_ and PADDING explanation
194196
195197 clang2py test/data/test-record.c
196198
197199This outputs:
200+ ``` py
201+ # ...
198202
199- # ...
200-
201- class struct_Node2(Structure):
202- _pack_ = True # source:False
203- _fields_ = [
204- ('m1', ctypes.c_ubyte),
205- ('PADDING_0', ctypes.c_ubyte * 7),
206- ('m2', POINTER_T(struct_Node)),]
207-
208- # ...
203+ class struct_Node2 (Structure ):
204+ _pack_ = True # source:False
205+ _fields_ = [
206+ (' m1' , ctypes.c_ubyte),
207+ (' PADDING_0' , ctypes.c_ubyte * 7 ),
208+ (' m2' , POINTER_T(struct_Node)),]
209209
210+ # ...
211+ ```
210212The PADDING_0 field is added to force the ctypes memory Structure to align fields offset with the definition given
211213by the clang compiler.
212214
0 commit comments