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..084df7d542 --- 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..db11caf724 --- /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}") diff --git a/python-bindings/tasks.py b/python-bindings/tasks.py index c1f796e9a0..2f5e5b558d 100644 --- a/python-bindings/tasks.py +++ b/python-bindings/tasks.py @@ -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() @@ -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( @@ -137,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") @@ -145,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 @@ -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) @@ -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,