【问题标题】:InternalsVisibleTo not working for Managed C++InternalsVisibleTo 不适用于托管 C++
【发布时间】:2010-09-29 21:23:22
【问题描述】:

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

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

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

在项目 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中的cmets,我把属性改成如下,还是不行。

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

【问题讨论】:

  • 请从“c++”重新标记为“c++cli”谢谢

标签: .net c++-cli internalsvisibleto


【解决方案1】:

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

#using <A.dll> as_friend

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

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

我也很失望,InternalsVisibleToAttribute 文档中没有提到这一点。我需要在C++ documentation 中四处寻找信息。

编辑InternalsVisisbleTo 的文档已经更新,包含指向Friend Assemblies (C++) 文档的链接。

【讨论】:

  • 您是否找到了让 C# 程序集看到另一个使用 C++ 构建的内部结构的方法?据我所知,没有办法在 c# 中设置像 as_friend 这样的东西。
  • FWIW,您不需要使用 #ifdefs 来引用正确的 DLL。相反,您可以在项目属性、C/C++、General、Resolve #using 引用中设置#using 引用的路径。在这里,您可以使用配置宏,例如 $(ConfigurationName) 等来指定使用的程序集的路径。
【解决方案2】:

注意:

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

让 .NET 机制在 #using 指令之后自行决定如何处理此库。

是的,将库添加到 Properties -> C/C++ -> General -> AdditionalUsingDirectories 中的列表中。

【讨论】:

    猜你喜欢
    • 2013-11-15
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2018-10-20
    • 2018-12-09
    • 2022-01-05
    相关资源
    最近更新 更多