python - 具有不明确标识符的空指针

标签 python c++ ctypes void-pointers

请原谅任何语法错误。我的 C++ 代码的设置与此类似:

template<typename T>
void addytox(T *x, T *y, int n)
{
   for(int i = 0; i < n; ++i) {
       x[i] += y[i];
   }
   return;
}


void my_func(void *x, void *y, int n, int dtype)
{
   /* Here is where I am unsure of how to do a simple static cast using 
   the dtype identifier. I want to avoid long code using a switch or 
   if/else that would check all possible conditions, for example having 
   code that looks like this:

      if (dtype == 0) {
          addytox((int*)x, (int*)y, n);
      }
      else if (dtype == 1) {
          addytox((float*)x, (float*)y, n);
      }
      else if (dtype == 2) {
          addytox((double*)x, (double*)y, n);
      }
      else {
          //Print/log some error...
          exit;
      }

      return;
   */
}

之所以这样设置代码,是因为 my_func 指向一个 NumPy 数组,它可以是任何类型(int、float32、float64 等),而我通过 ctypes 从 Python 调用 my_func。我知道 C++ 不知道 NumPy 数组是什么类型,但我可以轻松地在 Python 中获取数据类型,并将其传递给 my_func(在本例中为 integer dtype)。我想知道的是,我是否可以使用该标识符并仅调用函数 addytox 一次,并使用正确的类型转换。

例如:

addytox((cast_type*)x, (cast_type*)y, n));

是否可以在 C++ 中做这样的事情,如果可以,我将如何去做?

谢谢。

最佳答案

不幸的是,据我了解,编译时使用模板确定类型不会在运行时帮助您。您几乎只能使用开关类型机制来确定您需要在运行时调用的类型。

但是,我可以分享一些出色的模板元编程技术。这些有助于弥合编译和运行时类型确定之间的差距。

// Generic Declaration. Note the default value.
// For any of the TypeId's not specialized, the compiler will give errors.
template<int TypeId = 0>
struct DispatchAddYToX;

// Specialize for typeId = 0, which let's say is int
template<>
struct DispatchAddYToX<0>  // Let's say TypeId 0 = int
{
    enum { MyId = 0 };
    typedef int MyType;

    void dispatch(void* x, void* y, int n, int dType)
    {
        // Expanded version, for clarity.
        if(dType == MyId)
        {
            // Awriiite! We have the correct type ID.
            // ADL should take care of lookup.
            addYToX((MyType*)x, (MyType*)y, n);
        }
        else
        {
            // If not the correct ID for int, try the next one.
            DispatchAddYToX<MyId + 1>::dispatch(x, y, n, dType);
        }
    }
};

// Specialize for typeId = 1, which let's say is float
template<>
struct DispatchAddYToX<1>  // Let's say TypeId 1 = float
{
    enum { MyId = 1 };
    typedef float MyType;

    void dispatch(void* x, void* y, int n, int dType)
    {
        // Nice and compact version
        (dType == MyId) ? addYToX((MyType*)x, (MyType*)y, n) :
                          DispatchAddYToX<MyId + 1>::dispatch(x, y, n, dType);
    }
};

... 
// And so on for the rest of the type id's.

// Now for a C-style wrapper.
// Use this with your python hook
void addYToXWrapper(void* x, void*y, int n, int dType)
{
    // Defaults to start at 0 (int)
    // Will replace the switch statement.
    DispatchAddYToX::dispatch(x, y, n, dType);
}

所以最后,这是一个花哨的开关表,它做的事情几乎是一样的。不过,在我看来,界面更简洁了:)

关于python - 具有不明确标识符的空指针,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/42795050/

相关文章:

python - 将评论框架迁移到 Django 时出错

c++ - 在 QQuickItem 上打开 QFileDialog

windows - 如何使用 python 2.7 移动 Windows 桌面图标?

python - 在python中从dll调用函数

python - 如何在 ctypes 中生成字符数组并将其指针作为函数参数传递

python - 如何根据备用列中的相应值将一列中的特定值添加到列表中

Python:类属性的继承(列表)

python - 闲置3秒后如何再次移动一圈?

c++ - 为什么我在 C 库中看到 THROW?

c++ - 如何使用 DCB 结构设置波特率 2.000.000