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" )]
答案 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”列表中。