Skip to content
Projects
Groups
Snippets
Help
Loading...
Help
Support
Keyboard shortcuts
?
Submit feedback
Contribute to GitLab
Sign in / Register
Toggle navigation
C
cython
Project overview
Project overview
Details
Activity
Releases
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Labels
Merge Requests
0
Merge Requests
0
Analytics
Analytics
Repository
Value Stream
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Commits
Open sidebar
nexedi
cython
Commits
066118b1
Commit
066118b1
authored
Oct 09, 2017
by
Marvin Teichmann
Committed by
gabrieldemarmiesse
May 19, 2018
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
Fixing c library tutorial
parent
353299cb
Changes
1
Hide whitespace changes
Inline
Side-by-side
Showing
1 changed file
with
141 additions
and
14 deletions
+141
-14
docs/src/tutorial/clibraries.rst
docs/src/tutorial/clibraries.rst
+141
-14
No files found.
docs/src/tutorial/clibraries.rst
View file @
066118b1
******************
Using
C
libraries
=================
******************
Apart
from
writing
fast
code
,
one
of
the
main
use
cases
of
Cython
is
to
call
external
C
libraries
from
Python
code
.
As
Cython
code
...
...
@@ -22,12 +24,30 @@ type that can encapsulate all memory management.
..
[
CAlg
]
Simon
Howard
,
C
Algorithms
library
,
http
://
c
-
algorithms
.
sourceforge
.
net
/
..
_download_and_install_calg
:
Download
&
Install
[
CAlg
]
==========================
You
can
download
CAlg
`
here
<
https
://
github
.
com
/
fragglet
/
c
-
algorithms
/
archive
/
master
.
zip
>`
_
.
You
may
want
to
test
whether
you
can
build
c
-
algorithms
on
your
system
using
(
not
necessary
)::
$
cd
c
-
algorithms
$
sh
autogen
.
sh
$
./
configure
$
make
to
install
CAlg
run
::
$
make
install
Defining
external
declarations
------------------------------
===============================
The
C
API
of
the
queue
implementation
,
which
is
defined
in
the
header
file
``
libcalg
/
queue
.
h
``,
essentially
looks
like
this
::
file
``
c
-
algorithms
/
src
/
queue
.
h
``,
essentially
looks
like
this
::
/*
file
:
queue
.
h
*/
...
...
@@ -52,7 +72,7 @@ file, say, ``cqueue.pxd``::
#
file
:
cqueue
.
pxd
cdef
extern
from
"
libcalg
/queue.h"
:
cdef
extern
from
"
c-algorithms/src
/queue.h"
:
ctypedef
struct
Queue
:
pass
ctypedef
void
*
QueueValue
...
...
@@ -123,7 +143,7 @@ provided ``.pxd`` files.
Writing
a
wrapper
class
-----------------------
=======================
After
declaring
our
C
library
's API, we can start to design the Queue
class that should wrap the C queue. It will live in a file called
...
...
@@ -172,7 +192,7 @@ the type.
Memory
management
-----------------
====================
Before
we
continue
implementing
the
other
methods
,
it
is
important
to
understand
that
the
above
implementation
is
not
safe
.
In
case
...
...
@@ -218,7 +238,7 @@ the init method::
Compiling
and
linking
---------------------
=====================
At
this
point
,
we
have
a
working
Cython
module
that
we
can
test
.
To
compile
it
,
we
need
to
configure
a
``
setup
.
py
``
script
for
distutils
.
...
...
@@ -232,10 +252,64 @@ Here is the most basic script for compiling a Cython module::
ext_modules
=
cythonize
([
Extension
(
"queue"
,
[
"queue.pyx"
])])
)
To
build
against
the
external
C
library
,
we
must
extend
this
script
to
include
the
necessary
setup
.
Assuming
the
library
is
installed
in
the
usual
places
(
e
.
g
.
under
``/
usr
/
lib
``
and
``/
usr
/
include
``
on
a
Unix
-
like
system
),
we
could
simply
change
the
extension
setup
from
To
build
against
the
external
C
library
,
we
need
to
make
sure
Cython
finds
the
necessary
libraries
.
There
are
two
ways
to
archive
this
.
First
we
can
tell
distutils
where
to
find
the
c
-
source
to
compile
the
:
file
:`
queue
.
c
`
implementation
automatically
.
Alternatively
,
we
can
build
and
install
C
-
Alg
as
system
library
and
dynamically
link
it
.
The
latter
is
useful
if
other
applications
also
use
C
-
Alg
.
Static
Linking
---------------
To
build
the
c
-
code
automatically
we
need
to
include
compiler
directives
in
`
queue
.
pyx
`::
#
distutils
:
sources
=
c
-
algorithms
/
src
/
queue
.
c
#
distutils
:
include_dirs
=
c
-
algorithms
/
src
/
cimport
cqueue
cdef
class
Queue
:
cdef
cqueue
.
Queue
*
_c_queue
def
__cinit__
(
self
):
self
.
_c_queue
=
cqueue
.
queue_new
()
if
self
.
_c_queue
is
NULL
:
raise
MemoryError
()
def
__dealloc__
(
self
):
if
self
.
_c_queue
is
not
NULL
:
cqueue
.
queue_free
(
self
.
_c_queue
)
The
``
sources
``
compiler
directive
gives
the
path
of
the
C
files
that
distutils
is
going
to
compile
.
In
general
all
relevant
header
files
should
be
found
in
``
include_dirs
``.
Now
we
can
build
the
project
using
::
$
python
setup
.
py
build_ext
-
i
And
test
whether
our
build
was
successful
::
$
python
-
c
'import queue; Q = queue.Queue()'
Dynamic
Linking
---------------
Dynamic
linking
is
useful
,
if
the
library
we
are
going
to
wrap
is
already
installed
on
the
system
.
To
perform
dynamic
linking
we
first
need
to
build
and
install
c
-
alg
.
Follow
the
instruction
in
paragraph
:
ref
:`
download_and_install_calg
`
to
install
the
library
.
Afterwards
the
file
:
file
:`/
usr
/
local
/
lib
/
libcalg
.
so
`
should
exist
.
..
note
::
This
path
may
be
different
on
different
platforms
,
so
you
will
need
to
adapt
the
rest
of
the
tutorial
depending
on
the
where
`
libcalg
.
so
`
is
on
your
system
.
In
this
approach
we
need
to
tell
the
setup
script
to
link
with
an
external
library
.
To
do
so
we
need
to
extend
the
setup
script
to
install
change
the
extension
setup
from
::
...
...
@@ -250,7 +324,11 @@ to
libraries
=[
"calg"
])
])
If
it
is
not
installed
in
a
'normal'
location
,
users
can
provide
the
Now
we
should
be
able
to
build
the
project
using
::
$
python
setup
.
py
build_ext
-
i
If
the
`
libcalg
`
is
not
installed
in
a
'normal'
location
,
users
can
provide
the
required
parameters
externally
by
passing
appropriate
C
compiler
flags
,
such
as
::
...
...
@@ -258,11 +336,17 @@ flags, such as::
LDFLAGS
=
"-L/usr/local/otherdir/calg/lib"
\
python
setup
.
py
build_ext
-
i
Before
we
run
the
module
,
we
also
need
to
make
sure
that
`
libcalg
`
is
in
the
`
LD_LIBRARY_PATH
`
environment
variable
,
e
.
g
.
by
setting
::
$
export
LD_LIBRARY_PATH
=$
LD_LIBRARY_PATH
:/
usr
/
local
/
lib
Once
we
have
compiled
the
module
for
the
first
time
,
we
can
now
import
it
and
instantiate
a
new
Queue
::
$
export
PYTHONPATH
=.
$
python
-
c
'import queue.Queue as Q ; Q()'
$
python
-
c
'import queue; Q = queue.Queue()'
However
,
this
is
all
our
Queue
class
can
do
so
far
,
so
let
's make it
more usable.
...
...
@@ -502,6 +586,49 @@ instead that accepts an arbitrary Python iterable::
for value in values:
self.append(value)
Now we can test our Queue implementation using a python script,
for example here :file:`test_queue.py`.::
from __future__ import absolute_import
from __future__ import division
from __future__ import print_function
import queue
Q = queue.Queue()
Q.append(10)
Q.append(20)
print(Q.peek())
print(Q.pop())
print(Q.pop())
try:
print(Q.pop())
except IndexError as e:
print("Error message:", e) # Prints "Queue is empty"
i = 10000
values = range(i)
start_time = time.time()
Q.extend(values)
end_time = time.time() - start_time
print("Adding {} items took {:1.3f} msecs.".format(i, 1000 * end_time))
for i in range(41):
Q.pop()
Q.pop()
print("The answer is:")
print(Q.pop())
As a quick test with 10000 numbers on the author'
s
machine
indicates
,
using
this
Queue
from
Cython
code
with
C
``
int
``
values
is
about
five
times
as
fast
as
using
it
from
Cython
code
with
Python
object
values
,
...
...
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment