通过 C++反对 C++通过Python编写代码?

发布于 2024-08-31 22:11:29 字数 807 浏览 7 评论 0原文

我用 C++ 编写了一些物理模拟代码,解析输入文本文件是它的瓶颈。作为输入参数之一,用户必须指定一个数学函数,该函数将在运行时被多次评估。 C++ 代码为此有一些预定义的函数类(它们实际上在数学方面相当复杂)和一些有限的解析能力,但我对这种构造根本不满意。

我需要的是算法和函数求值都保持快速,因此将它们保留为编译代码(最好将数学函数保留为 C++ 函数对象)是有利的。然而,我想到将整个模拟与 Python 粘合在一起:用户可以在 Python 脚本中指定输入参数,同时还可以在 Python 中实现存储、结果可视化 (matplotlib) 和 GUI。

我知道大多数时候,可以使用 SWIG 来公开 C++ 类,但我仍然对 Python 中用户定义的数学函数的解析有疑问:

是否可以以某种方式构造 C++ 函数对象在Python中并将其传递给C++算法? 例如,当我

f = WrappedCPPGaussianFunctionClass(sigma=0.5)
WrappedCPPAlgorithm(f)

在Python中调用时,它会返回一个指向C++对象的指针,然后该对象将被传递给需要这样一个指针的C++例程,或者类似的东西......(在这种情况下,不要问我有关内存管理的问题,尽管如此) :S)

要点是算法中不应该对 Python 代码进行回调。稍后我想扩展这个示例,以便在 Python 端也进行一些简单的表达式解析,例如函数的求和或乘积,并返回一些复合的解析树(如 C++ 对象),但现在让我们停留在基础知识上。

很抱歉发了这么长的帖子,并感谢您提前提出的建议。

I have written some physics simulation code in C++ and parsing the input text files is a bottleneck of it. As one of the input parameters, the user has to specify a math function which will be evaluated many times at run-time. The C++ code has some pre-defined function classes for this (they are actually quite complex on the math side) and some limited parsing capability but I am not satisfied with this construction at all.

What I need is that both the algorithm and the function evaluation remain speedy, so it is advantageous to keep them both as compiled code (and preferrably, the math functions as C++ function objects). However I thought of glueing the whole simulation together with Python: the user could specify the input parameters in a Python script, while also implementing storage, visualization of the results (matplotlib) and GUI, too, in Python.

I know that most of the time, exposing C++ classes can be done, e.g. with SWIG but I still have a question concerning the parsing of the user defined math function in Python:

Is it possible to somehow to construct a C++ function object in Python and pass it to the C++ algorithm?
E.g. when I call

f = WrappedCPPGaussianFunctionClass(sigma=0.5)
WrappedCPPAlgorithm(f)

in Python, it would return a pointer to a C++ object which would then be passed to a C++ routine requiring such a pointer, or something similar... (don't ask me about memory management in this case, though :S)

The point is that no callback should be made to Python code in the algorithm. Later I would like to extend this example to also do some simple expression parsing on the Python side, such as sum or product of functions, and return some compound, parse-tree like C++ object but let's stay at the basics for now.

Sorry for the long post and thx for the suggestions in advance.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

尘世孤行 2024-09-07 22:11:29

我一直在做类似的事情。最简单的解决方案,也是我通常选择的解决方案,因为如果没有别的原因,我很懒,就是将您的 API 扁平化为类似 C 的 API,然后仅在 Python(或您选择的其他语言)之间传递指针。

首先创建您的类,

class MyFunctionClass
{
  public:
    MyFunctionClass(int Param)
    ...
};

class MyAlgorithmClass
{
  public:
    MyAlgorithmClass(myfunctionclass& Func)
    ...
};

然后创建一个 C 风格的函数 api,用于创建和销毁这些类。我通常会平铺直叙地传递 void* ,因为我使用的语言无论如何都不会保持类型安全。这样就更容易了。只要确保在实际使用 void* 之前转换回正确的类型即可。

    void* CreateFunction(int Param)
    {
      return new MyFunctionClass(Param);
    }

    void DeleteFunction(void* pFunc)
    {
        if (pFunc)
            delete (MyFunctionClass*)pFunc;
    }

    void* CreateAlgorithm(void* pFunc)
    {
      return new MyAlgorithmClass(*(MyFunctionClass*)pFunc)
    }

    void DelteAlgorithm(void* pAlg)
    {
       if (pAlg)
           delete (MyAlgorithmClass*)pAlg;
    }

您所需要做的就是让 python 调用那些 C 风格的函数。事实上,它们可以(并且可能应该)是外部“c”函数,以使链接更加容易。

I do things similar to this all the time. The simplest solution, and the one I usually pick because, if nothing else, I'm lazy, is to flatten your API to a C-like API and then just pass pointers to and from Python (or your other language of choice).

First create your classes

class MyFunctionClass
{
  public:
    MyFunctionClass(int Param)
    ...
};

class MyAlgorithmClass
{
  public:
    MyAlgorithmClass(myfunctionclass& Func)
    ...
};

Then create a C-style api of functions that creates and destroys those classes. I usually flatted in out to pass void* around becuase the languages I use don't keep type safety anyway. It's just easier that way. Just make sure to cast back to the right type before you actually use the void*

    void* CreateFunction(int Param)
    {
      return new MyFunctionClass(Param);
    }

    void DeleteFunction(void* pFunc)
    {
        if (pFunc)
            delete (MyFunctionClass*)pFunc;
    }

    void* CreateAlgorithm(void* pFunc)
    {
      return new MyAlgorithmClass(*(MyFunctionClass*)pFunc)
    }

    void DelteAlgorithm(void* pAlg)
    {
       if (pAlg)
           delete (MyAlgorithmClass*)pAlg;
    }

No all you need to do is make python call those C-style function. In fact, they can (and probably should) be extern "c" functions to make the linking that much easier.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文