teleport/common/pyshell/include/pys.h

291 lines
11 KiB
C
Raw Normal View History

#ifndef __PYS_H__
#define __PYS_H__
#include <ex.h>
//=========================================================================
// Type define
//=========================================================================
#if defined(EX_OS_WIN32)
# define DYLIB_HANDLE HINSTANCE
#else
# define DYLIB_HANDLE void*
#endif
//=========================================================================
// Python API
//=========================================================================
#define MS_NO_COREDLL 1
#ifdef __cplusplus
extern "C" {
#endif
#if defined(EX_OS_WIN32)
# define PYS_USE_PYLIB_SHARED
# include <Python.h>
#elif defined(EX_OS_LINUX)
# define PYS_USE_PYLIB_STATIC
# include <Python.h>
#elif defined(EX_OS_MACOS)
# define PYS_USE_PYLIB_SHARED
# include <Python.h>
#else
# error This platform not supported yet.
#endif
#ifdef __cplusplus
}
#endif
#ifdef PYS_USE_PYLIB_SHARED
//========================================================
// WIN32
//========================================================
#define EXTDECLPROC(result, name, args) \
typedef result (__cdecl* __PROC__ ## name) args; \
extern __PROC__ ## name pylib_ ## name;
#define EXTDECLVAR(vartyp, name) \
typedef vartyp __VAR__ ## name; \
extern __VAR__ ## name* pylib_ ## name;
EXTDECLVAR(int, Py_FrozenFlag);
EXTDECLVAR(int, Py_NoSiteFlag);
EXTDECLVAR(int, Py_OptimizeFlag);
EXTDECLVAR(const char*, Py_FileSystemDefaultEncoding);
EXTDECLVAR(int, Py_VerboseFlag);
EXTDECLVAR(int, Py_IgnoreEnvironmentFlag);
EXTDECLVAR(int, Py_DontWriteBytecodeFlag);
EXTDECLVAR(int, Py_NoUserSiteDirectory);
EXTDECLPROC(void, Py_Initialize, (void));
EXTDECLPROC(void, Py_Finalize, (void));
EXTDECLPROC(void, Py_IncRef, (PyObject *));
EXTDECLPROC(void, Py_DecRef, (PyObject *));
EXTDECLPROC(void, Py_SetProgramName, (wchar_t *));
EXTDECLPROC(void, Py_SetPythonHome, (wchar_t *));
EXTDECLPROC(void, Py_SetPath, (wchar_t *)); /* new in Python 3 */
EXTDECLPROC(int, PySys_SetArgvEx, (int, wchar_t **, int));
EXTDECLPROC(PyObject *, PyImport_ImportModule, (const char *));
EXTDECLPROC(PyObject *, PyObject_GetAttrString, (PyObject *, const char *));
// in python3.0~3.4, it is _Py_char2wchar, but renamed to Py_DecodeLocale in python3.5. WTF.
//EXTDECLPROC(wchar_t *, _Py_char2wchar, (char *, size_t *));
//EXTDECLPROC(PyObject*, PyUnicode_FromWideChar, (const wchar_t*, size_t size ));
EXTDECLPROC(PyObject *, Py_BuildValue, (char *, ...));
EXTDECLPROC(void, PyErr_Clear, (void));
EXTDECLPROC(PyObject *, PyErr_Occurred, (void));
EXTDECLPROC(void, PyErr_Print, (void));
EXTDECLPROC(PyObject *, PyObject_Call, (PyObject *callable_object, PyObject *args, PyObject *kw));
EXTDECLPROC(int, PyArg_Parse, (PyObject *, const char *, ...));
EXTDECLPROC(PyObject *, PyObject_CallFunction, (PyObject *, char *, ...));
EXTDECLPROC(PyObject *, PyModule_GetDict, (PyObject *));
EXTDECLPROC(PyObject *, PyDict_GetItemString, (PyObject *, char *));
EXTDECLPROC(int, PyDict_SetItemString, (PyObject *dp, const char *key, PyObject *item));
EXTDECLPROC(long, PyLong_AsLong, (PyObject *));
EXTDECLPROC(PyObject *, PyLong_FromLong, (long));
EXTDECLPROC(PyObject *, PyLong_FromUnsignedLong, (unsigned long));
EXTDECLPROC(PyObject *, PyLong_FromUnsignedLongLong, (unsigned PY_LONG_LONG));
EXTDECLPROC(PyObject *, PyBytes_FromString, (const char *));
EXTDECLPROC(PyObject *, PyBytes_FromStringAndSize, (const char *, Py_ssize_t));
EXTDECLPROC(PyObject *, PyUnicode_FromString, (const char *));
EXTDECLPROC(PyObject *, PyBool_FromLong, (long));
EXTDECLPROC(int, PyImport_ExtendInittab, (struct _inittab *newtab));
EXTDECLPROC(PyObject *, PyModule_Create2, (struct PyModuleDef*, int apiver));
EXTDECLPROC(int, PyArg_ParseTuple, (PyObject *, const char *, ...));
EXTDECLPROC(PyObject *, PyTuple_Pack, (Py_ssize_t, ...));
#else // for linux, link to static python lib.
#define pylib_Py_FrozenFlag Py_FrozenFlag
#define pylib_Py_NoSiteFlag Py_NoSiteFlag
#define pylib_Py_OptimizeFlag Py_OptimizeFlag
#define pylib_Py_FileSystemDefaultEncoding Py_FileSystemDefaultEncoding
#define pylib_Py_VerboseFlag Py_VerboseFlag
#define pylib_Py_IgnoreEnvironmentFlag Py_IgnoreEnvironmentFlag
#define pylib_Py_DontWriteBytecodeFlag Py_DontWriteBytecodeFlag
#define pylib_Py_NoUserSiteDirectory Py_NoUserSiteDirectory
#define pylib_Py_Initialize Py_Initialize
#define pylib_Py_Finalize Py_Finalize
#define pylib_Py_IncRef Py_IncRef
#define pylib_Py_DecRef Py_DecRef
#define pylib_Py_SetProgramName Py_SetProgramName
#define pylib_Py_SetPythonHome Py_SetPythonHome
#define pylib_Py_SetPath Py_SetPath
#define pylib_PySys_SetArgvEx PySys_SetArgvEx
#define pylib_PyImport_ImportModule PyImport_ImportModule
#define pylib_PyObject_GetAttrString PyObject_GetAttrString
#define pylib_Py_BuildValue Py_BuildValue
#define pylib_PyErr_Clear PyErr_Clear
#define pylib_PyErr_Occurred PyErr_Occurred
#define pylib_PyErr_Print PyErr_Print
#define pylib_PyObject_Call PyObject_Call
#define pylib_PyArg_Parse PyArg_Parse
#define pylib_PyObject_CallFunction PyObject_CallFunction
#define pylib_PyModule_GetDict PyModule_GetDict
#define pylib_PyDict_GetItemString PyDict_GetItemString
#define pylib_PyDict_SetItemString PyDict_SetItemString
#define pylib_PyLong_AsLong PyLong_AsLong
#define pylib_PyLong_FromLong PyLong_FromLong
#define pylib_PyLong_FromUnsignedLong PyLong_FromUnsignedLong
#define pylib_PyLong_FromUnsignedLongLong PyLong_FromUnsignedLongLong
#define pylib_PyBytes_FromString PyBytes_FromString
#define pylib_PyBytes_FromStringAndSize PyBytes_FromStringAndSize
#define pylib_PyUnicode_FromString PyUnicode_FromString
#define pylib_PyBool_FromLong PyBool_FromLong
#define pylib_PyImport_ExtendInittab PyImport_ExtendInittab
#define pylib_PyModule_Create2 PyModule_Create2
#define pylib_PyArg_ParseTuple PyArg_ParseTuple
#define pylib_PyTuple_Pack PyTuple_Pack
#define pylib_Py_IncRef Py_IncRef
#define pylib_Py_DecRef Py_DecRef
#define pylib_PyBool_FromLong PyBool_FromLong
#define pylib_PyBool_FromLong PyBool_FromLong
#endif
#define PYLIB_XINCREF(o) pylib_Py_IncRef(o)
#define PYLIB_XDECREF(o) pylib_Py_DecRef(o)
#define PYLIB_DECREF(o) PYLIB_XDECREF(o)
#define PYLIB_INCREF(o) PYLIB_XINCREF(o)
#define PYLIB_RETURN_TRUE return pylib_PyBool_FromLong(1)
#define PYLIB_RETURN_FALSE return pylib_PyBool_FromLong(0)
typedef int PYS_BOOL;
#define PYS_TRUE 1
#define PYS_FALSE 0
//=========================================================================
// PyShell API
//=========================================================================
typedef unsigned long PYS_RET;
#define PYSR_OK 0x00000000
#define PYSR_FAILED 0x00000005
#if 0
#ifdef EX_OS_WIN32
# ifdef EX_DEBUG
# if defined(_M_X64)
# pragma comment(lib, "pys_64d.lib")
# elif defined(_M_IX86)
# pragma comment(lib, "pys_32d.lib")
# else
# error unsupport platform.
# endif
# else
# if defined(_M_X64)
# pragma comment(lib, "pys_64.lib")
# elif defined(_M_IX86)
# pragma comment(lib, "pys_32.lib")
# else
# error unsupport platform.
# endif
# endif
#endif
#endif
#ifdef __cplusplus
extern "C" {
#endif
typedef void* PYS_HANDLE;
// 创建一个PyShell句柄所有操作均对应此句柄进行一个进程仅有一个句柄
PYS_HANDLE pys_create(void);
// 销毁一个PyShell句柄
void pys_destroy(PYS_HANDLE* pysh);
// 使用指定的运行时路径进行初始化运行时路径中包含pythonXX.dll/python.zip/modules等等
PYS_BOOL pys_init_runtime(PYS_HANDLE pysh, const wchar_t* exec_file, const wchar_t* runtime_path);
// 设置python包搜索路径可多次调用进行追加可省略
PYS_BOOL pys_add_search_path(PYS_HANDLE pysh, const wchar_t* path);
// 设置python运行时的命令行参数可省略
void pys_set_argv(PYS_HANDLE pysh, int argc, wchar_t** argv);
// 追加python运行时的命令行参数可省略
void pys_add_arg(PYS_HANDLE pysh, const wchar_t* arg);
// 设置python解释器名称可省略默认为当前可执行程序文件名的绝对路径
void pys_set_program(PYS_HANDLE pysh, const wchar_t* program_name);
// 设置入口脚本文件名,可以是一个.py文件也可以是一个.zip文件
void pys_set_startup_file(PYS_HANDLE pysh, const wchar_t* filename);
// 设置启动模块名和入口函数名func_name为NULL时默认执行指定模块中的main函数
// 本函数可以省略,默认情况下:
// 如果startup_file是一个.py文件则默认module_name就是.py文件的文件名本身
// 如果startup_file是一个.zip文件则默认module_name是`pysmain`。
void pys_set_bootstrap_module(PYS_HANDLE pysh, const char* module_name, const char* func_name);
// 初始化模块的函数原型
typedef PyObject* (*pys_init_module_func)(void);
typedef struct PYS_BUILTIN_FUNC
{
const char* py_func_name; // Python中调用时使用的函数名
PyCFunction c_func_addr; // 对应的C的函数
PYS_BOOL have_args; // 此函数是否需要参数
const char* py_func_desc; // 此函数的文档注释可以为NULL。
}PYS_BUILTIN_FUNC;
typedef enum PYS_CONST_TYPE
{
PYS_CONST_BOOL, // Python中得到 True/False 的值
PYS_CONST_LONG, // Python中得到一个整数
PYS_CONST_STRING, // Python中得到一个字符串
PYS_CONST_BYTES // Python中得到一个Bytes类型数据
}PYS_CONST_TYPE;
typedef struct PYS_BUILTIN_CONST
{
char* py_const_name; // Python中调用时使用的变量名
PYS_CONST_TYPE type; // 常量类型
size_t size; // 常量数据的长度
void* buffer; // 常量数据的内容
}PYS_BUILTIN_CONST;
// 增加一个内建模块其中如果没有函数或常量那么对应的funcs/consts可以为NULL。
// 可多次调用本函数来创建多个内建模块。如果多次调用时使用相同的模块名,则函数和常量会追加到此模块中
// 同一个模块中,函数名和常量名不能重复(但可以通过大小写区分)
PYS_BOOL pys_add_builtin_module(PYS_HANDLE pysh, const char* module_name, pys_init_module_func init_func);
PyObject* pys_create_module(const char* module_name, PYS_BUILTIN_FUNC* funcs);
void pys_builtin_const_bool(PyObject* mod, const char* name, PYS_BOOL val);
void pys_builtin_const_long(PyObject* mod, const char* name, long val);
void pys_builtin_const_utf8(PyObject* mod, const char* name, const char* val); // val 必须是utf8编码的字符串
void pys_builtin_const_wcs(PyObject* mod, const char* name, const wchar_t* val);
void pys_builtin_const_bin(PyObject* mod, const char* name, const ex_u8* val, size_t size);
// 运行python解释器
int pys_run(PYS_HANDLE pysh);
#ifdef __cplusplus
}
#endif
#ifdef __cplusplus
class PysHandleHolder
{
public:
PysHandleHolder(PYS_HANDLE h) :m_handle(h) { }
~PysHandleHolder() { pys_destroy(&m_handle); }
private:
PYS_HANDLE m_handle;
};
#endif
#endif // __PYS_H__