Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

add C++ examples for ctypes #213

Merged
merged 6 commits into from
Aug 18, 2021
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
16 changes: 15 additions & 1 deletion python-bindings/cppmult.hpp
Original file line number Diff line number Diff line change
@@ -1 +1,15 @@
float cppmult(int int_param, float float_param);
#ifdef _MSC_VER
#define EXPORT_SYMBOL __declspec(dllexport)
#else
#define EXPORT_SYMBOL
#endif

#ifdef __cplusplus
extern "C" {
#endif

EXPORT_SYMBOL float cppmult(int int_param, float float_param);

#ifdef __cplusplus
}
#endif
8 changes: 6 additions & 2 deletions python-bindings/ctypes_test.py → python-bindings/ctypes_c_test.py
100755 → 100644
Original file line number Diff line number Diff line change
Expand Up @@ -2,13 +2,17 @@
""" Simple examples of calling C functions through ctypes module. """
import ctypes
import sys
import pathlib

if __name__ == "__main__":
libname = pathlib.Path().absolute()
print("libname: ", libname)
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is a good addition! nice


# Load the shared library into c types.
if sys.platform.startswith("win"):
c_lib = ctypes.CDLL("cmult.dll")
c_lib = ctypes.CDLL(libname / "cmult.dll")
else:
c_lib = ctypes.CDLL("libcmult.so")
c_lib = ctypes.CDLL(libname / "libcmult.so")

# Sample data for our call:
x, y = 6, 2.3
Expand Down
31 changes: 31 additions & 0 deletions python-bindings/ctypes_cpp_test.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
#!/usr/bin/env python
""" Simple examples of calling C functions through ctypes module. """
import ctypes
import sys
import pathlib

if __name__ == "__main__":
libname = pathlib.Path().absolute()
print("libname: ", libname)

# Load the shared library into c types.
if sys.platform.startswith("win"):
c_lib = ctypes.CDLL(libname / "cppmult.dll")
else:
c_lib = ctypes.CDLL(libname / "libcppmult.so")

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

# This will not work:
# answer = c_lib.cmult(x, y)

# This produces a bad answer:
answer = c_lib.cppmult(x, ctypes.c_float(y))
print(f" In Python: int: {x} float {y:.1f} return val {answer:.1f}")
print()

# You need tell ctypes that the function returns a float
c_lib.cppmult.restype = ctypes.c_float
answer = c_lib.cppmult(x, ctypes.c_float(y))
print(f" In Python: int: {x} float {y:.1f} return val {answer:.1f}")
35 changes: 24 additions & 11 deletions python-bindings/tasks.py
Original file line number Diff line number Diff line change
Expand Up @@ -64,18 +64,29 @@ def build_cmult(c, path=None):


@invoke.task()
def test_ctypes(c):
def test_ctypes():
"""Run the script to test ctypes"""
print_banner("Testing ctypes Module")
print_banner("Testing ctypes Module for C")
# pty and python3 didn't work for me (win).
if on_win:
invoke.run("python ctypes_test.py")
invoke.run("python ctypes_c_test.py")
else:
invoke.run("python3 ctypes_test.py", pty=True)
invoke.run("python3 ctypes_c_test.py", pty=True)


@invoke.task()
def build_cffi(c):
def test_ctypes_cpp():
"""Run the script to test ctypes"""
print_banner("Testing ctypes Module for C++")
# pty and python3 didn't work for me (win).
if on_win:
invoke.run("python ctypes_cpp_test.py")
else:
invoke.run("python3 ctypes_cpp_test.py", pty=True)


@invoke.task()
def build_cffi():
"""Build the CFFI Python bindings"""
print_banner("Building CFFI Module")
ffi = cffi.FFI()
Expand Down Expand Up @@ -108,14 +119,14 @@ def build_cffi(c):


@invoke.task()
def test_cffi(c):
def test_cffi():
"""Run the script to test CFFI"""
print_banner("Testing CFFI Module")
invoke.run("python cffi_test.py", pty=not on_win)


@invoke.task()
def build_cppmult(c):
def build_cppmult():
"""Build the shared library for the sample C++ code"""
print_banner("Building C++ Library")
invoke.run(
Expand All @@ -137,22 +148,22 @@ def compile_python_module(cpp_name, extension_name):


@invoke.task(build_cppmult)
def build_pybind11(c):
def build_pybind11():
"""Build the pybind11 wrapper library"""
print_banner("Building PyBind11 Module")
compile_python_module("pybind11_wrapper.cpp", "pybind11_example")
print("* Complete")


@invoke.task()
def test_pybind11(c):
def test_pybind11():
"""Run the script to test PyBind11"""
print_banner("Testing PyBind11 Module")
invoke.run("python3 pybind11_test.py", pty=True)


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


@invoke.task()
def test_cython(c):
def test_cython():
"""Run the script to test Cython"""
print_banner("Testing Cython Module")
invoke.run("python3 cython_test.py", pty=True)
Expand All @@ -173,7 +184,9 @@ def test_cython(c):
@invoke.task(
clean,
build_cmult,
build_cppmult,
test_ctypes,
test_ctypes_cpp,
build_cffi,
test_cffi,
build_pybind11,
Expand Down