summaryrefslogtreecommitdiff
path: root/tests/run/cpp_extern.srctree
diff options
context:
space:
mode:
Diffstat (limited to 'tests/run/cpp_extern.srctree')
-rw-r--r--tests/run/cpp_extern.srctree171
1 files changed, 171 insertions, 0 deletions
diff --git a/tests/run/cpp_extern.srctree b/tests/run/cpp_extern.srctree
new file mode 100644
index 000000000..85374b2d0
--- /dev/null
+++ b/tests/run/cpp_extern.srctree
@@ -0,0 +1,171 @@
+# mode: run
+# tag: cpp
+# ticket: 1839
+
+"""
+PYTHON setup.py build_ext --inplace
+PYTHON -c "from include_as_c_and_cpp import test; test()"
+PYTHON -c "from include_from_c_and_cpp import test; test()"
+PYTHON -c "from cdefines import test; test()"
+"""
+
+######## setup.py ########
+
+from Cython.Build import cythonize
+from Cython.Distutils.extension import Extension
+from distutils.core import setup
+import sys
+
+include_as_c_and_cpp = Extension(
+ "include_as_c_and_cpp",
+ ["include_as_c_and_cpp.pyx", "include_as_c.cpp", "include_as_cpp.cpp"],
+)
+include_from_c_and_cpp = Extension(
+ "include_from_c_and_cpp",
+ ["include_from_c_and_cpp.pyx", "include_from_c.c", "include_from_cpp.cpp"],
+)
+
+cdefines = Extension(
+ "cdefines",
+ ["cdefines.pyx", "cdefines_clean.c", "cdefines_plain.cpp"],
+ define_macros = [("CYTHON_EXTERN_C", 'extern "C"')],
+)
+
+ext_modules = [include_as_c_and_cpp, include_from_c_and_cpp]
+if sys.platform != "win32":
+ # It's very hard to get the command-line macro define to escape properly on Windows,
+ # so skip it
+ ext_modules.append(cdefines)
+
+setup(
+ ext_modules=cythonize(ext_modules),
+)
+
+
+######## include_as_c_and_cpp.pyx ########
+
+# distutils: language = c++
+
+from libcpp cimport vector
+
+cdef public vector.vector[int] get_vector():
+ return [1,2,3]
+
+cdef extern from "include_as_c_and_cpp_header.h":
+ cdef size_t size_vector1()
+ cdef size_t size_vector2()
+
+def test():
+ assert size_vector1() == 3
+ assert size_vector2() == 3
+
+######## include_as_c_and_cpp_header.h ########
+
+size_t size_vector1();
+size_t size_vector2();
+
+######## include_as_cpp.cpp ########
+
+#include <vector>
+#include "include_as_c_and_cpp.h"
+
+size_t size_vector1() {
+ return get_vector().size();
+}
+
+######## include_as_c.cpp ########
+
+#include <vector>
+extern "C" {
+// #include within `extern "C"` is legal.
+// We want to make sure here that Cython C++ functions are flagged as `extern "C++"`.
+// Otherwise they would be interpreted with C-linkage if the header is include within a `extern "C"` block.
+#include "include_as_c_and_cpp.h"
+}
+
+size_t size_vector2() {
+ return get_vector().size();
+}
+
+
+######## include_from_c_and_cpp.pyx ########
+
+cdef public char get_char():
+ return 42
+
+cdef extern from "include_from_c_and_cpp_header.h":
+ cdef int get_int1()
+ cdef int get_int2()
+
+def test():
+ assert get_int1() == 42
+ assert get_int2() == 42
+
+######## include_from_c_and_cpp_header.h ########
+
+int get_int1();
+int get_int2();
+
+######## include_from_c.c ########
+
+#include "include_from_c_and_cpp.h"
+
+int get_int1() { return (int)get_char(); }
+
+######## include_from_cpp.cpp ########
+
+extern "C" {
+#include "include_from_c_and_cpp.h"
+}
+
+extern "C" int get_int2() { return (int)get_char(); }
+
+
+######## cdefines.pyx ########
+
+# distutils: language = c++
+
+cdef public char get_char():
+ return 42
+
+cdef extern from "cdefines_header.h":
+ cdef int get_int1()
+ cdef int get_int2()
+
+def test():
+ assert get_int1() == 42
+ assert get_int2() == 42
+
+######## cdefines_header.h ########
+
+#ifdef __cplusplus
+ #define cdefines_EXTERN_C extern "C"
+#else
+ #define cdefines_EXTERN_C
+#endif
+
+cdefines_EXTERN_C int get_int1();
+int get_int2();
+
+######## cdefines_clean.c ########
+
+#undef CYTHON_EXTERN_C
+#define CYTHON_EXTERN_C
+#include "cdefines.h"
+
+int get_int1() { return (int)get_char(); }
+
+######## cdefines_plain.cpp ########
+
+#include "cdefines.h"
+
+int get_int2() { return (int)get_char(); }
+
+######## cdefines.py ##########
+
+# Dummy module so Windows test works
+import sys
+assert sys.platform == "win32"
+
+def test():
+ pass