我有一个项目,其中包含一些性能敏感的本机C ++标头,大量使用模板。对于这个项目,我们还包装头文件并添加一些粘合代码以向c#和其他.NET语言公开功能。我们将此标题称为“layout.h”,我们将假设它是第三方标题,我无法更改。
在混合模式C ++ / CLI程序集中,从代码中#pragma unmanaged(或#pramga managed(push,off))的地方出错并#include相对容易。当发生这种情况时,模板会生成IL,并且在运行代码时会获得额外的托管/非托管转换,并且性能会下降。
我的问题是,是否有一种方法可以在#include之前进行编译时检查,这样如果我意外地#include从错误的上下文中编译失败。
// File1.cpp, compiled in a mixed mode C++/CLI assembly with /clr
ASSERT_UNMANAGED()
#include <layout.h>
我天真的第一次尝试检查了#ifdef _MANAGED,但总是定义我是否在#pragma非托管代码块中。
答案 0 :(得分:1)
您可以编写ASSERT_MANAGED
或ASSERT_UNMANAGED
代码,这些代码将使用仅在编译托管或非托管时可用的构造。 ref class
声明是仅在使用托管时才可用的示例。
这有点肮脏,但它会起作用。
答案 1 :(得分:1)
必须将pragma指令直接插入包含文件中。这样,在包含文件的任何地方都会声明一个非托管部分。
很抱歉,您必须修改包含文件。
答案 2 :(得分:0)
这是一个可行的解决方案,它利用以下事实:内部函数始终被编译为本地(非托管)代码:
#include <intrin.h>
#define ASSERT_UNMANAGED() \
int TestFunc(void) { \
__pragma(warning(push)) \
__pragma(warning(error:4793)) \
auto aumt = [] () { return _bextr_u64(65537, 0, 8); }; \
__pragma(warning(pop)) \
return int(aumt()); }
#pragma unmanaged // Comment out this line and the assertion fails!
ASSERT_UNMANAGED()
#pragma managed
编辑:当然,如果只希望警告而不是编译失败,则可以删除3条__pragma(warning())
行。