标签: c-api

Lua C API:设置错误源信息

我正在实现一个简单的LUA在线解释器,它从纯文本(即C字符串)中获取多个LUA脚本并运行它们.一切正常,但现在我正在测试我的程序的响应,当这些脚本发生语法或运行时错误.

到目前为止,当发生错误时,在调用后lua_pcall我从栈中收到消息错误,如下所示:

[string "..."]:7: attempt to call field 'push' (a nil value)
Run Code Online (Sandbox Code Playgroud)

现在,我想要的是LUA的运行时用[string "..."]虚拟文件名替换令牌(记住解释器从字符串中获取LUA代码),这样如果用户使用名称"my.lua"提交虚拟脚本,那么错误消息从LUA的运行时为该脚本引发的格式为:

my.lua:7: attempt to call field 'push' (a nil value)
Run Code Online (Sandbox Code Playgroud)

我试图分析LUA的源代码,以了解LUA解释器如何成功实现此目的.到目前为止,我发现的是,lua_loadstring()并且lua_loadfile()不同之处在于后者将"@"前面的文件名称推入堆栈.来自LUA的源代码(lauxlib.c):

LUALIB_API int luaL_loadfilex (lua_State *L, const char *filename,
                                         const char *mode) {
  LoadF lf;
  int status, readstatus;
  int c;
  int fnameindex = lua_gettop(L) + 1; /* index of filename on the stack */
  if (filename == NULL) {
    lua_pushliteral(L, "=stdin");
    lf.f = stdin;
  }
  else { …
Run Code Online (Sandbox Code Playgroud)

c lua c-api

3
推荐指数
1
解决办法
467
查看次数

为什么 PyObject_Print 崩溃?

我一直在使用 Python 3.3 C-API,看看是否可以在计划中的即将进行的项目中使用它,但几乎立即遇到了问题。

即使是这么简单的代码也会崩溃并返回 0xc0000005:

#include <Python.h>
#include <cstdio>

int main(){
    Py_Initialize();

    Py_IncRef(Py_True); //just in case?
    PyObject_Print(Py_True,stdout,Py_PRINT_RAW);
    Py_DecRef(Py_True);

    Py_Finalize();
    return 0;
}
Run Code Online (Sandbox Code Playgroud)

测试显示 PyObject_Print 正在生成崩溃。这段代码和/或我的设置有什么问题?

c++ python c-api python-3.x

2
推荐指数
1
解决办法
2652
查看次数

如何从C访问asyncio/uvloop循环

我是python的新手,但是有一个使用uvloop的异步python应用程序,它使用我创建的C api模块,它也需要访问异步循环.

1)asyncio还没有这个c-api?任何在C中使用事件循环的hack?这是在哪里讨论?

2)uvloop使用我在C中熟悉的libuv.如果我可以抓取uv_loop_t指针,我可以挂钩循环.我想我可以:

A)使用PyObject*到uvloop的循环计算uv_loop_t*的偏移并使用它?假设我知道PyObject_HEAD的长度?

libuv_loop = (uv_loop_t*)((void*)(loop)+0x8);

struct __pyx_obj_6uvloop_4loop_Loop {
    PyObject_HEAD
    uv_loop_t *uvloop;
Run Code Online (Sandbox Code Playgroud)

B)或非hacky修改uvloop以暴露循环指针.因为我从来没有看过cython代码,所以我完全无能为力.我可以在循环上创建一个python函数,从我的C代码调用它并获取C指针吗?喜欢:

(uv_loop_t*)PyObject_CallFunctionObjArgs( getLoop, NULL )
Run Code Online (Sandbox Code Playgroud)

通过在这里添加getLoop:

https://github.com/MagicStack/uvloop/blob/master/uvloop/loop.pyx

cdef uv.uv_loop_t* _getLoop(self):
    return self.uvloop
Run Code Online (Sandbox Code Playgroud)

cython c-api python-asyncio uvloop

2
推荐指数
1
解决办法
322
查看次数

通过 C API 访问 tensorflow 2.0 SavedModel 的输入和输出张量

我无法从加载了 C_API 的 tensorflow 2.0 SavedModel 运行推理,因为我无法按名称访问输入和输出操作。

我通过 TF_LoadSessionFromSavedModel(...) 成功加载了会话:

#include <tensorflow/c/c_api>

...

TF_Status* status = TF_NewStatus();
TF_Graph*  graph  = TF_NewGraph();
TF_Buffer* r_opts = TF_NewBufferFromString("",0);
TF_Buffer* meta_g = TF_NewBuffer();

TF_SessionOptions* opts = TF_NewSessionOptions();
const char* tags[] = {"serve"};

TF_Session* session = TF_LoadSessionFromSavedModel(opts, r_opts, "saved_model/tf2_model", tags, 1, graph, meta_g, status);

if ( TF_GetCode(status) != TF_OK ) exit(-1); //does not happen
Run Code Online (Sandbox Code Playgroud)

但是,尝试使用以下方法设置输入和输出张量时出现错误:

TF_Operation* inputOp  = TF_GraphOperationByName(graph, "input"); //works with "serving_default_input"
TF_Operation* outputOp = TF_GraphOperationByName(graph, "prediction"); //does not work
Run Code Online (Sandbox Code Playgroud)

我作为参数传递的名称被分配给保存模型的输入和输出 keras 层,但不在加载的graph …

c c-api tensorflow tensorflow-serving tensorflow2.0

2
推荐指数
1
解决办法
1315
查看次数

带有递归的Python C API - 段错误

我在C++中使用python的C API(2.7)将python树结构转换为C++树.代码如下:

  • python树以递归方式实现为具有子列表的类.叶节点只是原始整数(不是类实例)

  • 我加载模块并从C++调用蟒方法,使用从代码这里,它返回树,python_tree的一个实例,作为一个++中的PyObject℃.

  • 递归遍历获得的PyObject.要获得孩子的名单,我这样做:

    PyObject* attr = PyString_FromString("children");
    PyObject* list = PyObject_GetAttr(python_tree,attr);
    for (int i=0; i<PyList_Size(list); i++) {
        PyObject* child = PyList_GetItem(list,i); 
        ...
    
    Run Code Online (Sandbox Code Playgroud)

非常简单,它可以工作,直到我最终遇到分段错误,调用PyObject_GetAttr(Objects/object.c:1193,但我看不到API代码).它似乎发生在访问树的最后一个叶节点上.

我很难确定问题所在.使用C API进行递归是否有任何特殊注意事项?我不确定我是否需要使用Py_INCREF/Py_DECREF,或者使用这些函数.我并不完全理解API的工作原理.任何帮助深表感谢!

编辑:一些最小的代码:

void VisitTree(PyObject* py_tree) throw (Python_exception)
{
    PyObject* attr = PyString_FromString("children");
    if (PyObject_HasAttr(py_tree, attr)) // segfault on last visit
    {
        PyObject* list = PyObject_GetAttr(py_tree,attr);
        if (list)
        {
            int size = PyList_Size(list);
            for (int i=0; i<size; i++)
            {
                PyObject* py_child = PyList_GetItem(list,i);
                PyObject *cls = PyString_FromString("ExpressionTree");
                // check …
Run Code Online (Sandbox Code Playgroud)

python recursion segmentation-fault c-api

1
推荐指数
1
解决办法
873
查看次数

使用Python C API将Python的int列表传递给C函数

我在使用MacOS High Sierra上的Python3.6 anaconda发行版处理传递给Python C API包装函数的int列表时遇到问题.我想将传入的int列表转换为我可以在C中使用的int数组.

这里有一个类似的问题使用Python/C APIPython列表传递给C函数,我可以开始工作,但处理一个int列表似乎是不同的.

这是我到目前为止所拥有的.

static PyObject * myModule_sumIt(PyObject *self, PyObject *args) {
  PyObject *lst; 
  if(!PyArg_ParseTuple(args, "O", &lst)) {
    Py_DECREF(lst);
    return NULL;
  }

  int n = PyObject_Length(lst);
  printf("\nLength of list passed in is %d\n", n);

  int nums[n];
  int sum = 0;
  for (int i = 0; i < n; i++) {
     PyLongObject *item = PyList_GetItem(lst, i);
     sum += item;
     printf("\ni = %d\titem = %d\tsum = %d\n", i, item, sum);
     Py_DECREF(item);
  }

  Py_DECREF(lst); …
Run Code Online (Sandbox Code Playgroud)

c python c-api

1
推荐指数
1
解决办法
60
查看次数

如何防止删除用作共享指针的原始指针?

我为C ++类实现了C-API,该类使用其他对象的共享指针来访问它们。在我的C-API中,我当然只能获得原始指针。因此,我将C-API中的原始指针“转换”为共享指针,然后将其与C ++类方法一起使用:

method(std::shared_ptr<dataType>(raw-pointer));
Run Code Online (Sandbox Code Playgroud)

现在,我遇到的问题是,在“方法”的末尾,总是会调用共享指针析构函数,并且不幸的是,它杀死了我的原始指针指向的对象(我不想要)。因此,如何防止原始指针被杀死?

我已经尝试过像reset()或swap()这样的共享指针功能,但是它们都没有让我的原始指针走...

method(std::shared_ptr<dataType>(raw-pointer));
Run Code Online (Sandbox Code Playgroud)

预期的结果是,此函数返回后,原始指针e仍指向有效对象。实际上,原始指针然后指向已删除的对象。

c++ shared-ptr c-api raw-pointer

1
推荐指数
1
解决办法
126
查看次数