我有一个工具链,其中生成头文件(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
中,但这也不起作用。
我没办法了。这是不是根本无法解决?
2条答案
按热度按时间xggvc2p61#
你至少可以通过使用适当的标志来获得GCC或Clang的警告:
-Wmissing-declarations
用于GCC-Wmissing-prototypes
(Clang)Clang还提供了
-Wmissing-declarations
,但它并没有做同样的事情。GCC也提供了
-Wmissing-prototypes
,但不支持C++,我不知道为什么。See also this question.
vd2z7a6w2#
我找到了一个解决方案,它实际上是漂亮的,但相当黑客。
简单地将生成的头文件包含在命名空间中是行不通的:
问题并不直接源于
header.hpp
中的内容,而是源于生成的头文件中包含的jni.h
中的内容。但是,由于
jni.h
具有头保护,因此可以在包含生成的头之前将jni.h
包含在实现文件中!因为所有生成的函数都是
extern "C"
,所以对于JNI调用它们来说,C++是否将它们放在名称空间中并不重要。因为C没有命名空间,所以在对象文件中,命名空间消失了!