diff --git a/samples/python_extension/README.md b/samples/python_extension/README.md index cd6ced6d626..4cb791768a2 100644 --- a/samples/python_extension/README.md +++ b/samples/python_extension/README.md @@ -3,16 +3,17 @@ This example shows how to use Kotlin/Native programs from other execution environments, such as Python. Python has C native interface, which could be used to organize a bridge with the Kotlin/Native application. File `kotlin_bridge.c` contains translation code between Kotlin and Python -lands. +lands. This demo works on Linux, Windows (64-bit) or macOS hosts. To build and run the sample do the following: -* Install Python with development headers, i.e. +* Install Python with development headers, i.e. on Linux ``` sudo apt install python-dev ``` -* Run `build.sh`, it will ask for superuser password to install Python extension +* Run `build.sh`, it will ask for superuser password to install Python extension. + Use build.bat on Windows. * On macOS copy Kotlin binary to extension's directory and change install name with `install_name_tool` tool, i.e. ``` @@ -39,7 +40,7 @@ To build and run the sample do the following: The example works as following. Kotlin/Native API is implemented in `Server.kt`, and we run Kotlin/Native compiler with `-produce dynamic` option. Compiler produces two artifacts: `server_api.h` which is C language API - to all public functions and classes available in the application. `libserver.dylib` or `libserver.so` + to all public functions and classes available in the application. `libserver.dylib` or `libserver.so` or `server.dll` shared object contains C bridge to all above APIs. This C bridge looks like a C struct, reflecting all scopes in program, with operations available. For example, diff --git a/samples/python_extension/build.bat b/samples/python_extension/build.bat new file mode 100644 index 00000000000..a58a4a5cf40 --- /dev/null +++ b/samples/python_extension/build.bat @@ -0,0 +1,16 @@ +setlocal +set DIR=. + +if defined KONAN_HOME ( + set "PATH=%KONAN_HOME%\bin;%PATH%" +) else ( + set "PATH=..\..\dist\bin;..\..\bin;%PATH%" +) +konanc -p dynamic src/main/kotlin/Server.kt -o server + +rem Prepare MSVC build environment, and .lib file for linking with our .dll. +SET VS90COMNTOOLS=%VS140COMNTOOLS% +\Program Files (x86)\Microsoft Visual Studio 14.0\VC\bin\lib.exe" /def:server.def /out:server.lib /machine:X64 + +python src/main/python/setup.py install + \ No newline at end of file diff --git a/samples/python_extension/src/main/c/kotlin_bridge.c b/samples/python_extension/src/main/c/kotlin_bridge.c index 0843b758b90..bbff61490b5 100644 --- a/samples/python_extension/src/main/c/kotlin_bridge.c +++ b/samples/python_extension/src/main/c/kotlin_bridge.c @@ -23,7 +23,13 @@ // Note, that as we cache this in the global, and Kotlin/Native object references // are currently thread local, we make this global a TLS variable. -static __thread server_kref_demo_Server server = { 0 }; +#ifdef _MSC_VER +#define TLSVAR __declspec(thread) +#else +#define TLSVAR __thread +#endif + +static TLSVAR server_kref_demo_Server server = { 0 }; static T_(Server) getServer(void) { if (!server.pinned) { @@ -32,7 +38,7 @@ static T_(Server) getServer(void) { return server; } -static server_kref_demo_Session getSession(PyObject* args) { +static T_(Session) getSession(PyObject* args) { T_(Session) result = { 0 }; long long pinned; if (PyArg_ParseTuple(args, "L", &pinned)) { @@ -46,7 +52,7 @@ static PyObject* open_session(PyObject* self, PyObject* args) { char* string_arg = NULL; int int_arg = 0; if (PyArg_ParseTuple(args, "is", &int_arg, &string_arg)) { - server_kref_demo_Session session = __ kotlin.demo.Session.Session(string_arg, int_arg); + T_(Session) session = __ kotlin.demo.Session.Session(string_arg, int_arg); result = Py_BuildValue("L", session.pinned); } return result;