Python C API PyArg_ParseTupleAndKeywords在第二次函数调用时失败

Python C API PyArg_ParseTupleAndKeywords fails on second function call

提问人:kpm 提问时间:11/6/2023 最后编辑:kpm 更新时间:11/6/2023 访问量:23

问:

我目前正面临python c api的一个奇怪问题。它只发生在 1 台机器上,我无法在其他机器上重现该错误。

在第二次调用()时,我收到错误。 如果我只传递而不是作为代码第二次调用的第四个参数,则不会出错。b=...fail secondary argument 1 must be string, not tupleFalseasynchronous=Falseb

第一次调用总是成功。如果我交换两个调用,它将保持不变(第一次成功,第二次失败)。可能是什么问题?

python代码:

    try:
        print("connecting server 1")
        a = XRPythonOPC.Startup("Matrikon.OPC.Simulation.1","","{F8582CF2-88FB-11D0-B850-00C0F0104305}", asynchronous=False)
    except Exception as e:
      print("Failed to connect opc python servers1 ")
    try:
            print("connecting server 2")
            b = XRPythonOPC.Startup("Softing.OPCToolbox.C++.Sample.Demo.DA.1","","{5B5EBB5B-706E-404E-93D5-72A77212A14B}", asynchronous=False)   
    except Exception as e:
       print("Failed to connect 2")  

Python C API 代码 (C++):

static PyObject* Startup(PyTypeObject* /*type*/, PyObject* args, PyObject* keywds)
{
   const char*  ServerName = "";
   const char*  NodeName   = "";
   const char*  ClsID      = "";
   PyObject*    Async      = Py_True;
   
   static char* kwlist[]   = { "server_name", "node", "clsid", "asynchronous", NULL };

// fails here
   if (!PyArg_ParseTupleAndKeywords(args, keywds, "|sssO", (kwlist), &ServerName, &NodeName, &ClsID, &Async))
   {
     return NULL;
   }

   PyObject* obj = PyObject_Call(reinterpret_cast<PyObject*>(&XRPythonOPCType), args, keywds);
   
   return obj;
}

static int Init(XRPythonOPC* self, PyObject* args, PyObject* keywds)
{
   static char* kwlist[]   = { "server_name", "node", "clsid", "asynchronous", NULL };

   const char*  ServerName = "";
   const char*  NodeName   = "";
   const char*  ClsID      = "";
   //int         Async      = 1;
   PyObject*    Async      = Py_True;


   if (!PyArg_ParseTupleAndKeywords(args, keywds, "|sssO", (kwlist), &ServerName, &NodeName, &ClsID, &Async))
   {
     PyErr_SetString(PyExc_RuntimeError, "Either server_name or clsid needs to be provided to connect to a server or failed to parse arguments");
  
     return -1;
   }

   // Set Server, Node, Clsid, Async
   ///...
   //
  return 0;

}

打印 Startup 内部的类型时,给了我 .但这不应该是str,str,str,bool吗?tupleiterator, str, str,str

我还确保我在所有机器上都有相同的 python 版本。

      PyObject*    iterator   = PyObject_GetIter(args);
      PyObject*    Item = iterator;
      if (iterator)
     {
        //Item = PyIter_Next(iterator);
        while (Item != nullptr)
        {
          std::wcout << XRPyStringAsWstring(PyObject_GetAttrString((PyObject*)(Py_TYPE(Item)), "__name__"))
                     << std::endl;
         Item = PyIter_Next(iterator);
       }
     }
蟒蛇 c++17 python-c-api

评论


答: 暂无答案