gpt4 book ai didi

c++ - 如何最好地在不支持它的C++语言中实现函数指针?

转载 作者:行者123 更新时间:2023-12-01 14:58:10 25 4
gpt4 key购买 nike

例如,OpenCL不支持函数指针。一些针对嵌入式硬件的工具链也没有。 RPC需要等效于可在不相交的堆中工作的函数指针。因此,希望有足够的现有技术来获得已知的(尽管对我而言还不是)好的解决方案。

我已经将此问题标记为“C++”,尽管我知道看起来像C++但没有函数指针的语言实际上不是C++。它仍然是最合适的。我有可用的模板等,只是没有太多的运行时支持。

例如,可能要求程序员通过指针将枚举分配给他们想传递的每个函数,并编写一个对每个函数进行直接调用的开关。另外,传递该枚举的元素(而不是函数的地址),并使用并集进行操作以处理参数的变化。

或者,可以对函数的符号名称进行哈希处理(半自动分配值),然后根据这些哈希值编写开关。这就是我今天要做的,但是我想消除对自定义编译器的支持。

手动写出任何一个开关,并在需要时添加一个条目不是很好。因此,也许可以通过在全局数组上展开循环来构建if / else链。

这里没有类型安全性,因此每种功能类型应该分别使用散列/枚举/数组/其他类型。那将删除一些工会。

经过几个月的反复思考,我没有看到一个干净/可维护的解决方案(这不是定制的编译器通过)。欢迎思想。

最佳答案

您在使用开关的正确轨道上。

早在1999年-2001年,我是一个项目的主要开发者,此项目自nearly vanished from the web开始,在Apple的Quicktime中进行实时立体3D渲染。

它提供了一种定制的电影格式,可以拍摄标准的2D视频,并将其与256级深度轨道结合起来并渲染每个帧。

回放提供了一个输出选择:

  • 不同种类的有色眼镜:蓝绿色,红绿色等,在新颖的产品中很常见,其中3D是通过掩膜偏移
  • 实现的
  • 不同颜色的单色眼镜,其中颜色仅用于提供深度效果-对于精细的详细科学和采矿数据非常有用,例如查看岩石
  • 同步快门式LCD眼镜,该眼镜以60Hz的频率运行,插入到120Hz的CRT内嵌,
  • 非常早期的无眼镜展示架(每场约10万美元,用于 session )。

  • 它可以在当时的Windows和经典Mac设备上运行,以24fps的速度进行实时渲染。在G3 iMac 350MHz PowerPC等硬件上不容易。

    它还具有调整每帧深度渲染效果的能力。您可以选择在屏幕的前面或后面显示电影,并调整深度幅度以使事物看起来有多远。

    因此,再加上不同的电影格式,需要打开 很多的内容,这些内容可能会不断变化。

    我认为这是我编程生涯的顶峰。这是一个有趣而又极富挑战性的项目,需要解决 以及如何在Quicktime中提供此3D渲染,以及获得性能方面的技术挑战。在2000年的WWDC上,Apple QuickTime的工程师表示祝贺,并为我们做到了而感到震惊。所有操作均使用标准的QuickTime API完成,并且运行非常稳定,没有涉及任何黑客。

    下面的大代码示例显示了我如何使用模板和开关。嵌套的switch语句分解了上面讨论的每帧变量。

    嵌套的开关每渲染一帧运行一次。它们导致调用一个独特的功能,该功能循环渲染每个像素-我认为模板会产生大约700种不同的变化。

    我记得对CodeWarrior编译器的重大升级是在优化模板功能的项目中进行的。我们的编译时间增加了4倍,但是生成的代码更小,更快。

    // from rendererersP.h

    /**
    this template definition provides the implementation of the
    stereo pair algorithm for the argument class types.

    pass a single StereoRenderPars struct which tells the function
    about the source and destination data.
    */
    template<class ImageFormat,
    class DepthFormat,
    class GlassFormat,
    class DestinationFormat>
    void RenderStereoPair (StereoRenderPars *rp)
    {


    // from render_switch.cpp
    // the entry point for stereo
    int
    renderStereo(GlassType gt, ImageFormat sf, StereoRenderPars *rp, bool outputGrey)
    {
    int status = 0;

    switch (gt) // The GT Stringers!
    {
    case gtRLeftBGRight :
    {
    switch (outputGrey)
    {
    case true :
    {
    switch (sf)
    {
    case ifRGB :
    RenderStereoPair<ImageGrayRGB, DepthUnsigned24, GlassRLeftBGRight, ImageGrayRGB>(rp);
    break;
    case ifBGR :
    RenderStereoPair<ImageGrayBGR, DepthUnsigned24, GlassRLeftBGRight, ImageGrayBGR>(rp);
    break;
    case ifARGB :
    RenderStereoPair<ImageGrayARGB, DepthUnsigned32, GlassRLeftBGRight, ImageGrayARGB>(rp);
    break;
    case ifBGRA :
    RenderStereoPair<ImageGrayBGRA, DepthUnsigned32, GlassRLeftBGRight, ImageGrayBGRA>(rp);
    break;
    case if555RGB :
    RenderStereoPair<ImageGray555RGB, DepthUnsigned16, GlassRLeftBGRight, ImageGray555RGB>(rp);
    break;
    case if565RGB :
    RenderStereoPair<ImageGray565RGB, DepthUnsigned16, GlassRLeftBGRight, ImageGray565RGB>(rp);
    break;
    default :
    status = 1;
    }
    }
    break;
    case false :
    {
    switch (sf)
    {
    case ifRGB :
    RenderStereoPair<ImageRGB, DepthUnsigned24, GlassRLeftBGRight, ImageRGB>(rp);
    break;
    case ifBGR :
    RenderStereoPair<ImageBGR, DepthUnsigned24, GlassRLeftBGRight, ImageBGR>(rp);
    break;
    case ifARGB :
    RenderStereoPair<ImageARGB, DepthUnsigned32, GlassRLeftBGRight, ImageARGB>(rp);
    break;
    case ifBGRA :
    RenderStereoPair<ImageBGRA, DepthUnsigned32, GlassRLeftBGRight, ImageBGRA>(rp);
    break;
    case if555RGB :
    RenderStereoPair<Image555RGB, DepthUnsigned16, GlassRLeftBGRight, Image555RGB>(rp);
    break;
    case if565RGB :
    RenderStereoPair<Image565RGB, DepthUnsigned16, GlassRLeftBGRight, Image565RGB>(rp);
    break;
    default :
    status = 1;
    }
    }
    }
    }
    break;
    case gtBGLeftRRight :
    {
    switch (outputGrey)
    {
    case true :
    {
    switch (sf)
    {
    case ifRGB :
    RenderStereoPair<ImageGrayRGB, DepthUnsigned24, GlassBGLeftRRight, ImageGrayRGB>(rp);
    break;
    case ifBGR :
    RenderStereoPair<ImageGrayBGR, DepthUnsigned24, GlassBGLeftRRight, ImageGrayBGR>(rp);
    break;
    case ifARGB :
    RenderStereoPair<ImageGrayARGB, DepthUnsigned32, GlassBGLeftRRight, ImageGrayARGB>(rp);
    break;
    case ifBGRA :
    RenderStereoPair<ImageGrayBGRA, DepthUnsigned32, GlassBGLeftRRight, ImageGrayBGRA>(rp);
    break;
    case if555RGB :
    RenderStereoPair<ImageGray555RGB, DepthUnsigned16, GlassBGLeftRRight, ImageGray555RGB>(rp);
    break;
    case if565RGB :
    RenderStereoPair<ImageGray565RGB, DepthUnsigned16, GlassBGLeftRRight, ImageGray565RGB>(rp);
    break;
    default :
    status = 1;
    }
    }
    break;

    case false :
    {
    switch (sf)
    {
    case ifRGB :
    RenderStereoPair<ImageRGB, DepthUnsigned24, GlassBGLeftRRight, ImageRGB>(rp);
    break;
    case ifBGR :
    RenderStereoPair<ImageBGR, DepthUnsigned24, GlassBGLeftRRight, ImageBGR>(rp);
    break;
    case ifARGB :
    RenderStereoPair<ImageARGB, DepthUnsigned32, GlassBGLeftRRight, ImageARGB>(rp);
    break;
    case ifBGRA :
    RenderStereoPair<ImageBGRA, DepthUnsigned32, GlassBGLeftRRight, ImageBGRA>(rp);
    break;
    case if555RGB :
    RenderStereoPair<Image555RGB, DepthUnsigned16, GlassBGLeftRRight, Image555RGB>(rp);
    break;
    case if565RGB :
    RenderStereoPair<Image565RGB, DepthUnsigned16, GlassBGLeftRRight, Image565RGB>(rp);
    break;
    default :
    status = 1;
    }
    }
    }
    }
    break;

    关于c++ - 如何最好地在不支持它的C++语言中实现函数指针?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/59870562/

    25 4 0
    Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
    广告合作:1813099741@qq.com 6ren.com