Dot-Net

InternalsVisibleTo 不適用於託管 C++

  • October 28, 2019

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 中的評論,我將屬性更改為以下,但這仍然不起作用。

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

我找到了答案。C++ 的工作方式與其他語言不同。除了 InternalsVisibleTo 之外,您還必須使用as_friend關鍵字引用程序集**A。**由於 as_friend 不是“添加引用”對話框中的選項,因此您無法添加項目引用,而是需要在每個需要的 CPP 文件中添加引用。

#using <A.dll> as_friend

然後,您還需要更改程序集搜尋路徑以包含項目 A 的建構目錄。

恕我直言,這是託管 C++ 作為第二類語言的典型特徵。如果無法進行項目引用,您最終會在建構調試或發布目錄中引用程序集。這打破了依賴關係,當您將配置從調試更改為發佈時,唯一可以讓它引用正確 DLL 的方法是使用醜陋的#IFDEF DEBUG 和#using 的相對路徑。

我也對InternalsVisibleToAttribute文件中沒有提到這一點感到失望。我需要在C++ 文件中四處尋找資訊。

編輯InternalsVisisbleTo的文件已經更新為Friend Assemblies (C++)文件的連結。

引用自:https://stackoverflow.com/questions/417842