c++ 有没有什么方法可以将函数定义标记为out-of-line?

rsl1atfo  于 2023-06-25  发布在  其他
关注(0)|答案(2)|浏览(120)

我有一个工具链,其中生成头文件(javac -h,即Java Native Interface),但函数的实现是手动编写的。当假定的实现函数实际上没有实现报头声明的函数(通常是因为报头函数被更新)时,获得错误消息是非常有用的。
我知道如果头函数在一个命名空间中,我将如何做到这一点:

#pragma once
namespace N
{
    void f();
}
#include "header.hpp"
void N::f() { }
// good: compile error when you change the declaration in the header!

N::f()定义的函数如果没有声明(在头文件中)将无法编译。
然而,生成器并不把东西放在名称空间中(我发现没有办法告诉它),所以我尝试了全局名称空间,但这显然是不允许的:

#pragma once
void f();
#include "header.hpp"
void (::f)() { }
// error (on MSVC)
// warning "extra/explicit qualification on member 'f'" (on Clang/GCC)

我必须支持MSVC,所以禁止显示警告不是一种选择。
作为最后的手段,因为所有的函数都是extern "C",我想也许可以将#include "header.hpp" Package 在namespace中,但这也不起作用。
我没办法了。这是不是根本无法解决?

xggvc2p6

xggvc2p61#

你至少可以通过使用适当的标志来获得GCC或Clang的警告:

  • -Wmissing-declarations用于GCC
  • -Wmissing-prototypes(Clang)

Clang还提供了-Wmissing-declarations,但它并没有做同样的事情。
GCC也提供了-Wmissing-prototypes,但不支持C++,我不知道为什么。
See also this question.

vd2z7a6w

vd2z7a6w2#

我找到了一个解决方案,它实际上是漂亮的,但相当黑客。
简单地将生成的头文件包含在命名空间中是行不通的:

namespace jni
{
#include "header.hpp"
}

问题并不直接源于header.hpp中的内容,而是源于生成的头文件中包含的jni.h中的内容。
但是,由于jni.h具有头保护,因此可以在包含生成的头之前将jni.h包含在实现文件中!

#include <jni.h>
namespace jni
{
#include "header.hpp"
}

// Here, all the generated functions are in namespace jni.

因为所有生成的函数都是extern "C",所以对于JNI调用它们来说,C++是否将它们放在名称空间中并不重要。因为C没有命名空间,所以在对象文件中,命名空间消失了!

相关问题