【发布时间】:2016-06-19 12:29:30
【问题描述】:
我在 Visual Studio 2015 解决方案中有多个项目。其中几个项目执行 P/Invokes,例如:
[DllImport("IpHlpApi.dll")]
[return: MarshalAs(UnmanagedType.U4)]
public static extern int GetIpNetTable(IntPtr pIpNetTable, [MarshalAs(UnmanagedType.U4)]
ref int pdwSize, bool bOrder);
因此,我将所有 P/Invokes 移至单独的类库并将单个类定义为:
namespace NativeMethods
{
[
SuppressUnmanagedCodeSecurityAttribute(),
ComVisible(false)
]
public static class SafeNativeMethods
{
[DllImport("kernel32.dll", CharSet = CharSet.Auto, ExactSpelling = true)]
public static extern int GetTickCount();
// Declare the GetIpNetTable function.
[DllImport("IpHlpApi.dll")]
[return: MarshalAs(UnmanagedType.U4)]
public static extern int GetIpNetTable(IntPtr pIpNetTable, [MarshalAs(UnmanagedType.U4)]
ref int pdwSize, bool bOrder);
}
}
在其他项目中,这段代码被称为:
int result = SafeNativeMethods.GetIpNetTable(IntPtr.Zero, ref bytesNeeded, false);
所有编译都没有错误或警告。
现在在代码上运行 FxCop 会给出警告:
警告 CA1401 更改 P/Invoke 的可访问性 'SafeNativeMethods.GetIpNetTable(IntPtr, ref int, bool)' 所以它是 从其程序集外部不再可见。
好的。将可访问性更改为 internal 为:
[DllImport("IpHlpApi.dll")]
[return: MarshalAs(UnmanagedType.U4)]
internal static extern int GetIpNetTable(IntPtr pIpNetTable, [MarshalAs(UnmanagedType.U4)]
ref int pdwSize, bool bOrder);
现在导致以下硬错误:
错误 CS0122 'SafeNativeMethods.GetIpNetTable(IntPtr, ref int, bool)' 由于其保护级别而无法访问
那么我怎样才能在没有错误或警告的情况下完成这项工作?
提前感谢您的帮助,因为我已经绕了几个小时了!
【问题讨论】:
-
FxCop 抱怨,因为公开原生方法被认为是不好的风格。要以这种方式重构您的程序集,并且仍然对外界隐藏 PInvokes,您必须将它们设为内部,并为您希望访问的每个其他程序集添加 InternalsVisibleTo 属性到该程序集。
-
或者,当然,不要使用单独的程序集,只需使用带有 P/Invokes 的单个源(作为内部)并将其包含在每个需要它们的项目中(例如作为 svn 外部,或引用共享位置)。
-
@Zastai 我是这些概念的新手 :( 举个例子会很有帮助。谢谢。我特别喜欢你的第二个想法,但不知道该怎么做。
标签: c# pinvoke native-methods