Skip to content

Commit 8788205

Browse files
authored
Merge pull request #213 from adam-dziedzic/ctype_cpp_example
add C++ examples for ctypes
2 parents 426f5fa + 8305fa3 commit 8788205

File tree

4 files changed

+76
-14
lines changed

4 files changed

+76
-14
lines changed

python-bindings/cppmult.hpp

Lines changed: 15 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1 +1,15 @@
1-
float cppmult(int int_param, float float_param);
1+
#ifdef _MSC_VER
2+
#define EXPORT_SYMBOL __declspec(dllexport)
3+
#else
4+
#define EXPORT_SYMBOL
5+
#endif
6+
7+
#ifdef __cplusplus
8+
extern "C" {
9+
#endif
10+
11+
EXPORT_SYMBOL float cppmult(int int_param, float float_param);
12+
13+
#ifdef __cplusplus
14+
}
15+
#endif

python-bindings/ctypes_test.py renamed to python-bindings/ctypes_c_test.py

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2,13 +2,17 @@
22
""" Simple examples of calling C functions through ctypes module. """
33
import ctypes
44
import sys
5+
import pathlib
56

67
if __name__ == "__main__":
8+
libname = pathlib.Path().absolute()
9+
print("libname: ", libname)
10+
711
# Load the shared library into c types.
812
if sys.platform.startswith("win"):
9-
c_lib = ctypes.CDLL("cmult.dll")
13+
c_lib = ctypes.CDLL(libname / "cmult.dll")
1014
else:
11-
c_lib = ctypes.CDLL("libcmult.so")
15+
c_lib = ctypes.CDLL(libname / "libcmult.so")
1216

1317
# Sample data for our call:
1418
x, y = 6, 2.3

python-bindings/ctypes_cpp_test.py

Lines changed: 31 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,31 @@
1+
#!/usr/bin/env python
2+
""" Simple examples of calling C functions through ctypes module. """
3+
import ctypes
4+
import sys
5+
import pathlib
6+
7+
if __name__ == "__main__":
8+
libname = pathlib.Path().absolute()
9+
print("libname: ", libname)
10+
11+
# Load the shared library into c types.
12+
if sys.platform.startswith("win"):
13+
c_lib = ctypes.CDLL(libname / "cppmult.dll")
14+
else:
15+
c_lib = ctypes.CDLL(libname / "libcppmult.so")
16+
17+
# Sample data for our call:
18+
x, y = 6, 2.3
19+
20+
# This will not work:
21+
# answer = c_lib.cmult(x, y)
22+
23+
# This produces a bad answer:
24+
answer = c_lib.cppmult(x, ctypes.c_float(y))
25+
print(f" In Python: int: {x} float {y:.1f} return val {answer:.1f}")
26+
print()
27+
28+
# You need tell ctypes that the function returns a float
29+
c_lib.cppmult.restype = ctypes.c_float
30+
answer = c_lib.cppmult(x, ctypes.c_float(y))
31+
print(f" In Python: int: {x} float {y:.1f} return val {answer:.1f}")

python-bindings/tasks.py

Lines changed: 24 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -64,18 +64,29 @@ def build_cmult(c, path=None):
6464

6565

6666
@invoke.task()
67-
def test_ctypes(c):
67+
def test_ctypes():
6868
"""Run the script to test ctypes"""
69-
print_banner("Testing ctypes Module")
69+
print_banner("Testing ctypes Module for C")
7070
# pty and python3 didn't work for me (win).
7171
if on_win:
72-
invoke.run("python ctypes_test.py")
72+
invoke.run("python ctypes_c_test.py")
7373
else:
74-
invoke.run("python3 ctypes_test.py", pty=True)
74+
invoke.run("python3 ctypes_c_test.py", pty=True)
7575

7676

7777
@invoke.task()
78-
def build_cffi(c):
78+
def test_ctypes_cpp():
79+
"""Run the script to test ctypes"""
80+
print_banner("Testing ctypes Module for C++")
81+
# pty and python3 didn't work for me (win).
82+
if on_win:
83+
invoke.run("python ctypes_cpp_test.py")
84+
else:
85+
invoke.run("python3 ctypes_cpp_test.py", pty=True)
86+
87+
88+
@invoke.task()
89+
def build_cffi():
7990
"""Build the CFFI Python bindings"""
8091
print_banner("Building CFFI Module")
8192
ffi = cffi.FFI()
@@ -108,14 +119,14 @@ def build_cffi(c):
108119

109120

110121
@invoke.task()
111-
def test_cffi(c):
122+
def test_cffi():
112123
"""Run the script to test CFFI"""
113124
print_banner("Testing CFFI Module")
114125
invoke.run("python cffi_test.py", pty=not on_win)
115126

116127

117128
@invoke.task()
118-
def build_cppmult(c):
129+
def build_cppmult():
119130
"""Build the shared library for the sample C++ code"""
120131
print_banner("Building C++ Library")
121132
invoke.run(
@@ -137,22 +148,22 @@ def compile_python_module(cpp_name, extension_name):
137148

138149

139150
@invoke.task(build_cppmult)
140-
def build_pybind11(c):
151+
def build_pybind11():
141152
"""Build the pybind11 wrapper library"""
142153
print_banner("Building PyBind11 Module")
143154
compile_python_module("pybind11_wrapper.cpp", "pybind11_example")
144155
print("* Complete")
145156

146157

147158
@invoke.task()
148-
def test_pybind11(c):
159+
def test_pybind11():
149160
"""Run the script to test PyBind11"""
150161
print_banner("Testing PyBind11 Module")
151162
invoke.run("python3 pybind11_test.py", pty=True)
152163

153164

154165
@invoke.task(build_cppmult)
155-
def build_cython(c):
166+
def build_cython():
156167
"""Build the cython extension module"""
157168
print_banner("Building Cython Module")
158169
# Run cython on the pyx file to create a .cpp file
@@ -164,7 +175,7 @@ def build_cython(c):
164175

165176

166177
@invoke.task()
167-
def test_cython(c):
178+
def test_cython():
168179
"""Run the script to test Cython"""
169180
print_banner("Testing Cython Module")
170181
invoke.run("python3 cython_test.py", pty=True)
@@ -173,7 +184,9 @@ def test_cython(c):
173184
@invoke.task(
174185
clean,
175186
build_cmult,
187+
build_cppmult,
176188
test_ctypes,
189+
test_ctypes_cpp,
177190
build_cffi,
178191
test_cffi,
179192
build_pybind11,

0 commit comments

Comments
 (0)