From 684c1d786f0741b6836d4a238b47f860866d908e Mon Sep 17 00:00:00 2001 From: Adam Dziedzic Date: Fri, 30 Jul 2021 11:18:52 -0400 Subject: [PATCH 1/5] add C++ examples for ctypes --- python-bindings/cppmult.hpp | 16 +++++++++- .../{ctypes_test.py => ctypes_c_test.py} | 8 +++-- python-bindings/ctypes_cpp_test.py | 31 +++++++++++++++++++ 3 files changed, 52 insertions(+), 3 deletions(-) rename python-bindings/{ctypes_test.py => ctypes_c_test.py} (79%) mode change 100755 => 100644 create mode 100644 python-bindings/ctypes_cpp_test.py diff --git a/python-bindings/cppmult.hpp b/python-bindings/cppmult.hpp index 9569d04ba2..b608ee8d3b 100644 --- a/python-bindings/cppmult.hpp +++ b/python-bindings/cppmult.hpp @@ -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 diff --git a/python-bindings/ctypes_test.py b/python-bindings/ctypes_c_test.py old mode 100755 new mode 100644 similarity index 79% rename from python-bindings/ctypes_test.py rename to python-bindings/ctypes_c_test.py index 762b78e82c..442cbacc6e --- a/python-bindings/ctypes_test.py +++ b/python-bindings/ctypes_c_test.py @@ -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) + # 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 diff --git a/python-bindings/ctypes_cpp_test.py b/python-bindings/ctypes_cpp_test.py new file mode 100644 index 0000000000..af8bdd3b1d --- /dev/null +++ b/python-bindings/ctypes_cpp_test.py @@ -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}") From b7e56fc5eac35d875623b25a49355c87feb464fd Mon Sep 17 00:00:00 2001 From: Adam Dziedzic Date: Fri, 30 Jul 2021 12:01:54 -0400 Subject: [PATCH 2/5] reformatted with flake8 and black --- python-bindings/ctypes_c_test.py | 2 +- python-bindings/ctypes_cpp_test.py | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/python-bindings/ctypes_c_test.py b/python-bindings/ctypes_c_test.py index 442cbacc6e..084df7d542 100644 --- a/python-bindings/ctypes_c_test.py +++ b/python-bindings/ctypes_c_test.py @@ -6,7 +6,7 @@ if __name__ == "__main__": libname = pathlib.Path().absolute() - print('libname: ', libname) + print("libname: ", libname) # Load the shared library into c types. if sys.platform.startswith("win"): diff --git a/python-bindings/ctypes_cpp_test.py b/python-bindings/ctypes_cpp_test.py index af8bdd3b1d..db11caf724 100644 --- a/python-bindings/ctypes_cpp_test.py +++ b/python-bindings/ctypes_cpp_test.py @@ -6,7 +6,7 @@ if __name__ == "__main__": libname = pathlib.Path().absolute() - print('libname: ', libname) + print("libname: ", libname) # Load the shared library into c types. if sys.platform.startswith("win"): From b37bf1c7c3c0d76c9f7f4565351d3b6552453a0d Mon Sep 17 00:00:00 2001 From: Adam Dziedzic Date: Fri, 30 Jul 2021 13:13:47 -0400 Subject: [PATCH 3/5] add the C++ for ctypes in tasks.py --- python-bindings/tasks.py | 41 ++++++++++++++++++++++++++-------------- 1 file changed, 27 insertions(+), 14 deletions(-) diff --git a/python-bindings/tasks.py b/python-bindings/tasks.py index c1f796e9a0..a17420d16b 100644 --- a/python-bindings/tasks.py +++ b/python-bindings/tasks.py @@ -17,15 +17,15 @@ def clean(c): """Remove any built objects""" for file_pattern in ( - "*.o", - "*.so", - "*.obj", - "*.dll", - "*.exp", - "*.lib", - "*.pyd", - "cffi_example*", # Is this a dir? - "cython_wrapper.cpp", + "*.o", + "*.so", + "*.obj", + "*.dll", + "*.exp", + "*.lib", + "*.pyd", + "cffi_example*", # Is this a dir? + "cython_wrapper.cpp", ): for file in glob.glob(file_pattern): os.remove(file) @@ -64,14 +64,25 @@ def build_cmult(c, path=None): @invoke.task() -def test_ctypes(c): +def test_ctypes_c(c): """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 test_ctypes_cpp(c): + """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() @@ -173,7 +184,9 @@ def test_cython(c): @invoke.task( clean, build_cmult, - test_ctypes, + build_cppmult, + test_ctypes_c, + test_ctypes_cpp, build_cffi, test_cffi, build_pybind11, From e89c79c2dba051c4c7965f8e6882d08262d8b1a7 Mon Sep 17 00:00:00 2001 From: Adam Dziedzic Date: Fri, 30 Jul 2021 13:20:47 -0400 Subject: [PATCH 4/5] revert to standard ctype command for the C language --- python-bindings/tasks.py | 22 +++++++++++----------- 1 file changed, 11 insertions(+), 11 deletions(-) diff --git a/python-bindings/tasks.py b/python-bindings/tasks.py index a17420d16b..ba7fe0f017 100644 --- a/python-bindings/tasks.py +++ b/python-bindings/tasks.py @@ -17,15 +17,15 @@ def clean(c): """Remove any built objects""" for file_pattern in ( - "*.o", - "*.so", - "*.obj", - "*.dll", - "*.exp", - "*.lib", - "*.pyd", - "cffi_example*", # Is this a dir? - "cython_wrapper.cpp", + "*.o", + "*.so", + "*.obj", + "*.dll", + "*.exp", + "*.lib", + "*.pyd", + "cffi_example*", # Is this a dir? + "cython_wrapper.cpp", ): for file in glob.glob(file_pattern): os.remove(file) @@ -64,7 +64,7 @@ def build_cmult(c, path=None): @invoke.task() -def test_ctypes_c(c): +def test_ctypes(c): """Run the script to test ctypes""" print_banner("Testing ctypes Module for C") # pty and python3 didn't work for me (win). @@ -185,7 +185,7 @@ def test_cython(c): clean, build_cmult, build_cppmult, - test_ctypes_c, + test_ctypes, test_ctypes_cpp, build_cffi, test_cffi, From 3ca2cc23b1303f4021d77c0231edd095342e15d9 Mon Sep 17 00:00:00 2001 From: Adam Dziedzic Date: Fri, 30 Jul 2021 15:01:30 -0400 Subject: [PATCH 5/5] remove unnecessary c parameters --- python-bindings/tasks.py | 18 +++++++++--------- 1 file changed, 9 insertions(+), 9 deletions(-) diff --git a/python-bindings/tasks.py b/python-bindings/tasks.py index ba7fe0f017..2f5e5b558d 100644 --- a/python-bindings/tasks.py +++ b/python-bindings/tasks.py @@ -64,7 +64,7 @@ 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 for C") # pty and python3 didn't work for me (win). @@ -75,7 +75,7 @@ def test_ctypes(c): @invoke.task() -def test_ctypes_cpp(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). @@ -86,7 +86,7 @@ def test_ctypes_cpp(c): @invoke.task() -def build_cffi(c): +def build_cffi(): """Build the CFFI Python bindings""" print_banner("Building CFFI Module") ffi = cffi.FFI() @@ -119,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( @@ -148,7 +148,7 @@ 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") @@ -156,14 +156,14 @@ def build_pybind11(c): @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 @@ -175,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)