From e78e99fffa149374cec27ba77204962fe04b46eb Mon Sep 17 00:00:00 2001 From: naksyn <59816245+naksyn@users.noreply.github.com> Date: Sun, 18 Feb 2024 14:24:59 -0800 Subject: [PATCH] added more languages Added C#, nim and go languages. --- .gitignore | 15 ++++++++ C#/embedder.cs | 53 ++++++++++++++++++++++++++++ C++/embedder.cpp | 89 ++++++++++++++++++++++++++++++++++++++++++++++++ go/embedder.go | 88 +++++++++++++++++++++++++++++++++++++++++++++++ nim/embedder.nim | 49 ++++++++++++++++++++++++++ 5 files changed, 294 insertions(+) create mode 100644 .gitignore create mode 100644 C#/embedder.cs create mode 100644 C++/embedder.cpp create mode 100644 go/embedder.go create mode 100644 nim/embedder.nim diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..40da7f2 --- /dev/null +++ b/.gitignore @@ -0,0 +1,15 @@ + +*.vsidx +embedder/.vs/embedder/v17/.suo +embedder/.vs/embedder/v17/Browse.VC.db +*.db-shm +*.opendb +*.ilk +*.obj +*.idb +*.pdb +*.exe +*.pdb +embedder/.vs/embedder/FileContentIndex/14571e3d-0243-4f53-85d8-94c6d5df27e2.vsidx +*.vsidx +embedder/.vs/embedder/v17/.suo diff --git a/C#/embedder.cs b/C#/embedder.cs new file mode 100644 index 0000000..ab029a4 --- /dev/null +++ b/C#/embedder.cs @@ -0,0 +1,53 @@ +/* +Author: @naksyn (c) 2024 + +Description: A Simple C# program to embed Python interpeter and load the strictly required libraries to bootstrap Pyramid + +Copyright 2024 +Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), +to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, +and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: +The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, +DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE +OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. +*/ + +using System; +using System.Runtime.InteropServices; + +class Program +{ + [DllImport("kernel32.dll", SetLastError = true)] + private static extern IntPtr LoadLibrary(string lpFileName); + + [DllImport("python310.dll", EntryPoint = "Py_InitializeEx", CallingConvention = CallingConvention.Cdecl)] + public static extern void Py_InitializeEx(int initsigs); + + [DllImport("python310.dll", EntryPoint = "PyRun_SimpleString", CallingConvention = CallingConvention.Cdecl)] + public static extern int PyRun_SimpleString(string code); + + [DllImport("python310.dll", EntryPoint = "Py_Finalize", CallingConvention = CallingConvention.Cdecl)] + public static extern void Py_Finalize(); + + static void Main(string[] args) + { + IntPtr ctypesHandle = LoadLibrary("_ctypes.pyd"); + IntPtr libffiHandle = LoadLibrary("libffi-7.dll"); + Py_InitializeEx(0); + + + string pythonCode = @" +print("paste Pyramid cradle here") +"; + + if (PyRun_SimpleString(pythonCode) != 0) + { + Console.WriteLine("Failed to execute Python code!"); + } + + Py_Finalize(); + } +} + diff --git a/C++/embedder.cpp b/C++/embedder.cpp new file mode 100644 index 0000000..781d2a1 --- /dev/null +++ b/C++/embedder.cpp @@ -0,0 +1,89 @@ +/* +Author: @naksyn (c) 2024 + +Description: A Simple C++ program to embed Python interpeter and load the strictly required libraries to bootstrap Pyramid + +Copyright 2024 +Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), +to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, +and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: +The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, +DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE +OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. +*/ + +#include +#include + + + +int main() { + + const LPCWSTR dllNames[] = { + L"python310.dll", //put the interpreter dll as first in the array + L"libffi-7.dll", // needed to access ctypes + L"_ctypes.pyd" // needed to access ctypes + }; + const int numDLLs = sizeof(dllNames) / sizeof(LPCWSTR); + + HMODULE hModules[numDLLs]; + for (int i = 0; i < numDLLs; ++i) { + hModules[i] = LoadLibrary(dllNames[i]); + if (hModules[i] == NULL) { + std::cerr << "Failed to load DLL: " << dllNames[i] << std::endl; + for (int j = 0; j < i; ++j) { + FreeLibrary(hModules[j]); + } + return 1; + } + } + std::cout << "All DLLs loaded successfully." << std::endl; + + + // Resolve Py_InitializeEx + typedef void (*PINITIALIZEEXFN)(int); + PINITIALIZEEXFN pInitializeEx = reinterpret_cast(GetProcAddress(hModules[0], "Py_InitializeEx")); + if (pInitializeEx == NULL) { + std::cerr << "Failed to resolve Py_InitializeEx function!" << std::endl; + FreeLibrary(hModules[0]); + return 1; + } + + pInitializeEx(0); + + typedef int (*PRUNSINGLESTRING)(const char*); + PRUNSINGLESTRING pRunSimpleString = reinterpret_cast(GetProcAddress(hModules[0], "PyRun_SimpleString")); + if (pRunSimpleString == NULL) { + std::cerr << "Failed to resolve PyRun_SimpleString function!" << std::endl; + FreeLibrary(hModules[0]); + return 1; + } + + + const char* pythonCode = R"( +print("paste Pyramid cradle here") +)"; + if (pRunSimpleString(pythonCode) != 0) { + std::cerr << "Failed to execute Python code!" << std::endl; + FreeLibrary(hModules[0]); + return 1; + } + + + typedef void (*PFINALIZEFN)(); + PFINALIZEFN pFinalize = reinterpret_cast(GetProcAddress(hModules[0], "Py_Finalize")); + if (pFinalize != NULL) { + pFinalize(); + } + + + for (int i = 0; i < numDLLs; ++i) { + FreeLibrary(hModules[i]); + } + + return 0; + +} + diff --git a/go/embedder.go b/go/embedder.go new file mode 100644 index 0000000..2307293 --- /dev/null +++ b/go/embedder.go @@ -0,0 +1,88 @@ +/* +Author: @naksyn (c) 2024 + +Description: A Simple Go program to embed Python interpeter and load the strictly required libraries to bootstrap Pyramid + +Copyright 2024 +Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), +to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, +and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: +The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, +DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE +OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. +*/ + +package main + +/* +#cgo LDFLAGS: -lkernel32 +#include +#include + + +void (*Py_Initialize)(void); +int (*PyRun_SimpleString)(const char *); +void (*Py_Finalize)(void); + + +HMODULE loadLibrary(const char* name) { + HMODULE hModule = LoadLibraryA(name); + if (hModule == NULL) { + fprintf(stderr, "Failed to load %s\n", name); + } + return hModule; +} + + +void loadPythonFunctions() { + HMODULE pythonDLL = loadLibrary("python310.dll"); + HMODULE libFFIDLL = loadLibrary("libffi-7.dll"); // Not directly used here, but loaded for dependency + HMODULE ctypesDLL = loadLibrary("_ctypes.pyd"); // Not directly used here, but loaded for dependency + + if (!(pythonDLL && libFFIDLL && ctypesDLL)) { + fprintf(stderr, "Failed to load one or more DLLs\n"); + return; + } + + *(FARPROC *)&Py_Initialize = GetProcAddress(pythonDLL, "Py_Initialize"); + *(FARPROC *)&PyRun_SimpleString = GetProcAddress(pythonDLL, "PyRun_SimpleString"); + *(FARPROC *)&Py_Finalize = GetProcAddress(pythonDLL, "Py_Finalize"); + + if (!Py_Initialize || !PyRun_SimpleString || !Py_Finalize) { + fprintf(stderr, "Failed to load one or more Python API functions\n"); + } +} + +// Wrappers +void cPyInitialize() { + Py_Initialize(); +} + +void cPyRun_SimpleString(const char* str) { + PyRun_SimpleString(str); +} + +void cPyFinalize() { + Py_Finalize(); +} +*/ +import "C" +import "unsafe" + +func main() { + + C.loadPythonFunctions() + C.cPyInitialize() + +// Execute Python Code + + pythonCode := ` +print("paste Pyramid cradle here") +` + cPythonCode := C.CString(pythonCode) + defer C.free(unsafe.Pointer(cPythonCode)) + C.cPyRun_SimpleString(C.CString(pythonCode)) + C.cPyFinalize() +} diff --git a/nim/embedder.nim b/nim/embedder.nim new file mode 100644 index 0000000..f8a9dfd --- /dev/null +++ b/nim/embedder.nim @@ -0,0 +1,49 @@ +#[ +Author: @naksyn (c) 2024 + +Description: A Simple nim program to embed Python interpeter and load the strictly required libraries to bootstrap Pyramid + +Copyright 2024 +Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), +to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, +and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: +The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, +DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE +OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. +]# + +import dynlib, os, strutils + +proc loadLibrary(name: string): pointer = + let libHandle = loadLib(name) + if libHandle == nil: + echo("Failed to load ", name) + return libHandle + +# Declare the types for the Python C API functions with dynamic linking +proc Py_InitializeEx(initsigs: cint) {.cdecl, dynlib: "python310.dll", importc: "Py_InitializeEx".} +proc PyRun_SimpleString(code: cstring): cint {.cdecl, dynlib: "python310.dll", importc: "PyRun_SimpleString".} +proc Py_Finalize() {.cdecl, dynlib: "python310.dll", importc: "Py_Finalize".} + +proc main() = + + discard loadLibrary("python310.dll") + discard loadLibrary("libffi-7.dll") # Loaded for dependency purposes + discard loadLibrary("_ctypes.pyd") # Loaded for dependency purposes + + Py_InitializeEx(0) + + + let pythonCode = """ +print("paste Pyramid cradle here") +""".cstring # Convert Nim string to C string for compatibility + + if PyRun_SimpleString(pythonCode) != 0: + echo "Failed to execute Python code!" + + Py_Finalize() + +when isMainModule: + main()