InternalsVisibleTo不适用于托管C ++

时间:2009-01-06 19:47:53

标签: .net c++-cli internalsvisibleto

InternalsVisibleTo不适用于我的托管C ++项目,但它适用于我的C#项目。任何帮助,将不胜感激。这是一个简化的布局。

项目 A - C#,我想要从 B / C 访问内部属性。
项目 B - 托管C ++。参考文献 A
项目 C - C#,引用 A

所有项目都使用相同的密钥签名。使用ILDASM或Reflector查看已编译的程序集,表明它们都已正确签名(当我注释掉内部属性用法时)。

在Project A 中的AssemblyInfo.cs中,我有以下InternalsVisibleTo;

[assembly: InternalsVisibleTo( "B, " +
   "PublicKey=00240000048000009400000006020000002400005253413100040000010001007" +
   "50098646D1C04C2A041FAAF801521A769535DE9A04CD3B4DEDCCBF73D1A6456BF4FE5881451" +
   "0E84983C72D0460B8BA85C52A9CACDC4A0785A08E247C335884C2049ECFE6B2C5E20A18FE4B" +
   "9BFF009ADA232E980D220B3C9586C9C5EE29C29AEE8853DB7BB90CF5A4C704F5244E1A1085C" +
   "4306008535049A0EBB00FE47E78DCB" )]

[assembly: InternalsVisibleTo( "C, " +
   "PublicKey=00240000048000009400000006020000002400005253413100040000010001007" +
   "50098646D1C04C2A041FAAF801521A769535DE9A04CD3B4DEDCCBF73D1A6456BF4FE5881451" +
   "0E84983C72D0460B8BA85C52A9CACDC4A0785A08E247C335884C2049ECFE6B2C5E20A18FE4B" +
   "9BFF009ADA232E980D220B3C9586C9C5EE29C29AEE8853DB7BB90CF5A4C704F5244E1A1085C" +
   "4306008535049A0EBB00FE47E78DCB" )]

钥匙被'切',所以我知道它们是正确的。

当我尝试编译时, A& C 编译正常,但项目 B 失败,

Error 1 error C3767: 'A::MyClass::MyProperty::get': candidate function(s) not accessible c:\Users\<snip>\CppClass.cpp 201 B

MSDN文档说这适用于C ++。是否有我需要做的错误或其他事情?

我是否有另一种方法可以保护财产,使其只能由我签署的集合使用?我知道我可以保护我的所有装配,但是我可以在这样的粒度级别上进行吗?

修改

根据MSDN中的评论,我将属性更改为以下内容,但仍然无效。

[assembly: InternalsVisibleTo( "B, " +
   "PublicKey=00240000048000009400000006020000002400005253413100040000010001007" +
   "50098646D1C04C2A041FAAF801521A769535DE9A04CD3B4DEDCCBF73D1A6456BF4FE5881451" +
   "0E84983C72D0460B8BA85C52A9CACDC4A0785A08E247C335884C2049ECFE6B2C5E20A18FE4B" +
   "9BFF009ADA232E980D220B3C9586C9C5EE29C29AEE8853DB7BB90CF5A4C704F5244E1A1085C" +
   "4306008535049A0EBB00FE47E78DCB" ),
InternalsVisibleTo( "C, " +
   "PublicKey=00240000048000009400000006020000002400005253413100040000010001007" +
   "50098646D1C04C2A041FAAF801521A769535DE9A04CD3B4DEDCCBF73D1A6456BF4FE5881451" +
   "0E84983C72D0460B8BA85C52A9CACDC4A0785A08E247C335884C2049ECFE6B2C5E20A18FE4B" +
   "9BFF009ADA232E980D220B3C9586C9C5EE29C29AEE8853DB7BB90CF5A4C704F5244E1A1085C" +
   "4306008535049A0EBB00FE47E78DCB" )]

2 个答案:

答案 0 :(得分:26)

我找到了答案。 C ++与其他语言的工作方式不同。除了InternalsVisibleTo之外,您还必须使用 as_friend 关键字引用程序集 A 。由于as_friend不是“添加引用”对话框中的选项,因此无法添加项目引用,而是需要在每个所需的CPP文件中添加引用。

#using <A.dll> as_friend

然后,您还需要更改程序集搜索路径以包含项目A的构建目录。

恕我直言,这是破解,典型的托管C ++是第二类语言。如果没有项目引用的能力,最终会在构建调试或发布目录中引用程序集。这打破了依赖关系,当你将配置从debug更改为release时,你可以让它引用正确的DLL的唯一方法是使用丑陋的#IFDEF DEBUG和#using的相对路径。

我也感到失望的是InternalsVisibleToAttribute文档中没有提到这一点。我需要在C++ documentation中寻找信息。

修改InternalsVisisbleTo的文档已更新,其中包含指向Friend Assemblies (C++)文档的链接。

答案 1 :(得分:0)

注意:

也许有人会帮助不要手动添加引用到“ #using as_friend”所包含的库中,因为如果它留在这样的引用中,则可能无法编译。

让.NET机制本身在#using指令之后决定对该库执行什么操作。

是的,将库添加到“属性-> C / C ++->常规-> AdditionalUsingDirectories”列表中。