• 在定义C++, C通用接口函数时让C++接口支持默认参数


    在SOUI4的开发中,所有SOUI核心对象都采用了一种类似COM接口的技术来导出接口。

    这所以采用这种方案,主要目的是为了让SOUI4支持C语言调用,扩展SOUI的使用场景。

    众所周知,C++函数的参数支持配置默认值,但C函数是不支持默认值的。

    比如定义了类似下面一个接口

    1 #undef INTERFACE
    2 #define INTERFACE IRenderTarget
    3 DECLARE_INTERFACE_(IRenderTarget, IObjRef)
    4 {
    5 //...
    6     STDMETHOD_(HRESULT, SelectObject)
    7     (THIS_ IRenderObj * pObj, IRenderObj * *ppOldObj) PURE;
    8 //...
    9 };

    IRenderTarget::SelectObject方法的功能是给当前的RenderTarget选择一个绘图对象,同时如果ppOldObj不为NULL,则通过ppOldObj返回当前正在使用的同类型绘图对象。

    很多时候用户并不关心原来的对象,所以通常给它置为NULL即可。这也是SOUI3及之前版本的默认参数。

    由于4.0中,该接口可能是在C++中引用,也可能是在C中引用,如果还是直接使用C++的方法给它设置默认参数NULL,在C中引用就会导致编译失败。

    是由于这个方法是控件自绘中常用的方法,为了减少升级SOUI3的代码到SOUI4的难度,我一直在想有没有办法能够兼容两种语言的特性。

    今天无意中想起来可以用一个简单的宏解决。

    于是我定义了下面的宏:

    1 #ifdef __cplusplus
    2 #define DEF_VAL(x) =x
    3 #else
    4 #define DEF_VAL(x)
    5 #endif//__cplusplus

    有了这个宏,我们就可以同时兼容C++和C语言了,上面的接口修改如下:

    1 #undef INTERFACE
    2 #define INTERFACE IRenderTarget
    3 DECLARE_INTERFACE_(IRenderTarget, IObjRef)
    4 {
    5 //...
    6     STDMETHOD_(HRESULT, SelectObject)
    7     (THIS_ IRenderObj * pObj, IRenderObj * *ppOldObj DEF_VAL(NULL)) PURE;
    8 //...
    9 };

    通过这样修改,经过测试,可以解决我的问题。

  • 相关阅读:
    LeetCode 623. Add One Row to Tree
    LeetCode 894. All Possible Full Binary Trees
    LeetCode 988. Smallest String Starting From Leaf
    LeetCode 979. Distribute Coins in Binary Tree
    LeetCode 814. Binary Tree Pruning
    LeetCode 951. Flip Equivalent Binary Trees
    LeetCode 426. Convert Binary Search Tree to Sorted Doubly Linked List
    LeetCode 889. Construct Binary Tree from Preorder and Postorder Traversal
    LeetCode 687. Longest Univalue Path
    LeetCode 428. Serialize and Deserialize N-ary Tree
  • 原文地址:https://www.cnblogs.com/setoutsoft/p/16120558.html
Copyright © 2020-2023  润新知