什么时候适合使用 extern 关键字而不使用 [DllImport] 属性?

2024-04-10

今天我重新阅读一些 .Net 文档时,我注意到该文档的第一部分extern关键词文档 https://msdn.microsoft.com/en-us/library/e59b22c5.aspx claims:

extern 修饰符用于声明外部实现的方法。常见用途当您使用互操作服务调用非托管代码时,extern 修饰符与 DllImport 属性一起使用。

引起我注意的是该文件指出“常见用途”extern是它与 DllImport 属性一起使用。这意味着还有其他不需要 DllImport 的用例。我不必将许多外部非托管库集成到我的应用程序中,但在所有情况下链接的方法都是使用 DllImport 定义的。

我通过 Google 和 MSDN 搜索了多个查询,但找不到案例或解释extern将使用关键字而不将方法定义为从非托管 dll 导入的外部方法。

您将如何以及何时使用extern没有定义关键字[DllImport(...)]方法定义上的属性?

请注意,这并不特定于使用extern定义别名时。这是关键字的不同用法,这种情况是在另一篇文章中概述 https://msdn.microsoft.com/en-us/library/ms173212.aspxMSDN C# 语言参考中。


我使用它的一种情况是,如果我是一名 Microsoft 开发人员,正在实现对 CLR 本身中定义的方法的调用。像GC._WaitForFullGCApproach:

[MethodImpl(MethodImplOptions.InternalCall)]
private static extern int _WaitForFullGCApproach(int millisecondsTimeout);

注:无DllImport。当然,这有点作弊——这仍然是对非托管方法的调用,只是没有显式引用 DLL。不过,凡人无法调用此类代码,因为它仅在mscorlib集会。

另一个应用InternalCall位于为 COM 生成的互操作类型中:

namespace Microsoft.Office.Interop.Excel {
    [DefaultMember("_Default")]
    [ClassInterface(0)]
    [ComSourceInterfaces("Microsoft.Office.Interop.Excel.AppEvents\0")]
    [Guid("00024500-0000-0000-C000-000000000046")]
    [TypeLibType(2)]
    [ComImport]
    public class ApplicationClass {
        // ...
        [DispId(302)]
        [MethodImpl(MethodImplOptions.InternalCall)]
        public virtual extern void Quit();
        // ...
    }
}

这些属性允许运行时将方法调用解析为对 COM 接口的调用。这种使用InternalCall is外部有效mscorlib, 明显地。您通常不会自己用 C# 编写此类代码;当您添加 COM 类型库作为引用时,它会根据需要生成。

C# 语言规范比 MSDN 更详细:

The extern修饰符通常与DllImport属性(§17.5.1),允许外部方法由 DLL(动态链接库)。执行环境可能支持 可以通过其他机制实现外部方法 假如。

从实现的角度来看,标记一个方法extern仅仅具有将方法的RVA(相对虚拟地址)设置为0的效果,将其标​​记为没有实现。属性如DllImport (and MethodImpl)对于向运行时描述如何定位方法的实际实现是必要的。 ECMA-335 的 I.9.4 节“方法实现元数据”对此进行了描述(以及DllImport and InternalCall似乎是目前唯一可用的方法)。

C# 编译器将允许您将方法标记为extern and not使用任何属性来指示实现所在的位置,但是任何具有此类方法的类型都将导致TypeLoadException在运行时。

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

什么时候适合使用 extern 关键字而不使用 [DllImport] 属性? 的相关文章

  • c# 从另一个类中的另一个静态事件引发事件

    需要帮助从另一个班级调用事件 我有已声明事件的课程 public class MxPBaseGridView GridView public event AddNewItemsToPopUpMenuEventHandler AddNewIt
  • 叮当错误?命名空间模板类的朋友

    以下代码在 clang 下无法编译 但在 gcc 和 VS 下可以编译 template
  • MFC CList 支持复制分配吗?

    我在 MSVC 中查找了 CList 定义afxtempl h http www cppdoc com example mfc classdoc MFC AFXTEMPL H html并记录在MSDN http msdn microsoft
  • 将 OpenCV Mat 转换为数组(可能是 NSArray)

    我的 C C 技能很生疏 OpenCV 的文档也相当晦涩难懂 有没有办法获得cv Mat data属性转换为数组 NSArray 我想将其序列化为 JSON 我知道我可以使用 FileStorage 实用程序转换为 YAML XML 但这不
  • 在 ASP.NET MVC 中将模型从视图传递到控制器

    我正在 ASP NET MVC 中开发我的第一个应用程序 但遇到了一个我无法解决的问题 即使在阅读了整个互联网之后也是如此 因此 我有几个使用视图模型创建的视图 它们是报告 这些视图模型是根据用户选择标准填充的 我正在尝试构建一种接受模型并
  • C# 处理标准输入

    我目前正在尝试通过命令行断开与网络文件夹的连接 并使用以下代码 System Diagnostics Process process2 new System Diagnostics Process System Diagnostics Pr
  • 有什么方法可以重载 C# 中的扩展方法吗?

    我有以下模型模式 public abstract class PARENTCLASS public class CHILD A CLASS PARENTCLASS public static class EXTENSION public s
  • 在 C# 中何时使用 ArrayList 而不是 array[]?

    我经常使用一个ArrayList而不是 正常 array 当我使用时 我感觉好像我在作弊 或懒惰 ArrayList 什么时候可以使用ArrayList在数组上 数组是强类型的 并且可以很好地用作参数 如果您知道集合的长度并且它是固定的 则
  • 如何使用递归查找数字中的最小元素 [C]

    好的 所以我正在准备我的 C 考试 当谈到递归时我有点卡住了我是大学一年级的学生 这对我来说似乎有点困难 练习要求在给定的数字中使用递归函数我需要找到最小的元素 例如 52873 是 2 程序需要打印 2 include
  • 为什么不能调用带有 auto& 参数的 const mutable lambda?

    include
  • 使用 OleDbCommandBuilder 时访问 SQL 语法错误

    我要在 C 中使用 OleDbDataAdapter 在 Access 数据库中插入数据 但收到错误消息INSERT INTO 命令中的语法错误 BackgroundWorker worker new BackgroundWorker Ol
  • 将错误代码映射到 C++ 中的字符串

    将错误代码从枚举映射到字符串的更有效方法是什么 在 C 中 例如 现在我正在做这样的事情 std string ErrorCodeToString enum errorCode switch errorCode case ERROR ONE
  • C++ 到 C# 事件处理

    所以我有我的C WinForm 应用程序 我从中调用我的C CLI MFC dll图书馆 但也有一些events在我的 C 库上 甚至此事件也发生在该库的本机 非 CLI 部分 我需要从我的 C 应用程序调用一些代码 并获取一些有关此事件的
  • 为什么 f(i = -1, i = -1) 是未定义的行为?

    我正在读关于违反评估顺序 http en cppreference com w cpp language eval order 他们举了一个令我困惑的例子 1 如果标量对象上的副作用相对于同一标量对象上的另一个副作用是无序的 则行为未定义
  • C 中使用 getrandom 实现随机浮点数

    我试图生成一个介于 0 和 1 之间的随机浮点数 无论是在 0 1 还是 0 1 对我来说都不重要 网上关于此的每个问题似乎都涉及rand 呼叫 播种time NULL 但我希望能够每秒多次调用我的程序 并每次都获得不同的随机数 这引导我找
  • 浮点字节序?

    我正在为实时海上模拟器编写客户端和服务器 并且由于我必须通过套接字发送大量数据 因此我使用二进制数据来最大化可以发送的数据量 我已经了解整数字节顺序以及如何使用htonl and ntohl为了规避字节顺序问题 但我的应用程序与几乎所有模拟
  • Autoconf 问题:“错误:C 编译器无法创建可执行文件”

    我正在尝试使用 GNU 自动工具构建一个用 C 编写的程序 但显然我设置错误 因为当configure运行 它吐出 configure error C compiler cannot create executables 如果我看进去con
  • Linq.Select() 中的嵌套表达式方法调用

    I use Select i gt new T 每次手动点击数据库后将我的实体对象转换为 DTO 对象 以下是一些示例实体和 DTOS 用户实体 public partial class User public int Id get set
  • 有没有办法直接在函数参数中格式化字符串而不是使用临时字符串?

    我有一个接受字符串 字符数组 作为参数的函数 void enterString char my string 当使用这个函数时 我经常发现自己想要输入格式化的字符串 我使用 sprintf 来做到这一点 然而 我每次都必须创建一个临时字符串
  • 将 char 绑定到枚举类型

    我有一段与此非常相似的代码 class someclass public enum Section START MID END vector section Full void ex for int i 0 i section

随机推荐

  • Rails 表单动态添加字段

    我正在尝试设置一组字段以根据需要动态显示 在模型中 我有以下字段 attr accessible instruct1 instruct2 instruct30 我希望表单只显示 instruct1 并带有一个按钮来添加 1 个字段 直到击中
  • 在 Apex 类中引用远程站点设置 URL?

    我有一个 webservice 类 它将位于托管包中并分发给多个客户端 该类当前有一个变量 其中包含它所访问的服务器的硬编码值 问题 每个客户端的服务器都不同 因此硬编码值不起作用 我认为由于每个客户端都必须将其服务器添加到其远程站点设置中
  • 如何比较 MySQL 数据库模式 [关闭]

    Closed 这个问题是无关 help closed questions 目前不接受答案 我正在寻找一个可以让我比较 MySQL 数据库模式的工具 哪个是最好的工具来做到这一点 Navicat 能够为您做到这一点 它还将同步两个 mysql
  • AES加密/解密

    以下是一些适用于字符串的代码 Public Function AESEncrypt ByVal PlainText As String ByVal Password As String ByVal salt As String Dim Ha
  • 如何在“git Push”之后在本地和远程撤消“git commit”

    我已经表演过git commit随后是一个git push 如何在本地和远程存储库上恢复该更改 git log commit 364705c23011b0fc6a7ca2d80c86cef4a7c4db7ac8 Author Michael
  • 开源 Twitter 克隆(在 Ruby/Python 中)[关闭]

    Closed 此问题正在寻求书籍 工具 软件库等的推荐 不满足堆栈溢出指南 help closed questions 目前不接受答案 是否有任何用 Ruby 或 Python 编写的生产就绪的开源 Twitter 克隆 我对功能丰富的实现
  • 如何备份 Django 数据库

    我有一个使用 Postgres 数据库的 Django 应用程序 我需要能够备份和恢复数据库 既确保没有数据丢失 又能够在测试期间将数据从生产服务器复制到开发服务器 似乎有几种不同的方法可以做到这一点 只需直接与数据库交互即可 因此 对于
  • CKEditor 如何在取消帖子时删除服务器中的图像文件

    我正在使用nodeJS 后端 react 前端 mongoDB 我安装了 CKEditor5 以便在船上发布许多图像 它可以完美地在我的服务器文件夹上上传图像CKfinder But 如果有人停止发布上传的图像 无用的图像将保留在我的服务器
  • 警告:远程 HEAD 引用不存在的引用,无法结帐

    由于不同原因 这似乎是一个常见的错误 我有一个简单的裸 git 存储库 名为 kiflea git 我像这样克隆它 git clone git kipdola be kiflea git 然后 git 告诉我 warning remote
  • Mockito 3 any() 严格存根参数不匹配

    我正在使用 Mockito 3 1 0 我正在尝试用以下语法模拟我的方法 when mockedObject myMethod any HttpServletRequest class thenReturn 1 myMethod很简单 pu
  • 如何在 Strawberry Perl 中更改@INC?

    我该如何改变 INC永久地 而不改变我的脚本 在 Strawberry Perl 中 我知道 I 但不想每次都调用该开关 要添加路径 请将环境变量 PERL5LIB 设置为这些路径 注意 这将影响您运行的所有 Perl 安装 操作方法 右键
  • Task.FromResult() 与 Task.Run()

    我最近遇到过不少情况async方法同步执行 但无论如何都会返回一个任务 因此可以等待它们 例如 public virtual Task CreateAsync TUser user ThrowIfDisposed if user null
  • File.isFile() 返回错误结果? [复制]

    这个问题在这里已经有答案了 public class Test public static void isFile System out println new File D a log isFile public static void
  • 为什么不能在构造函数中实例化该类的同一对象?

    public class Run public static void main String args A a1 new A class A public A A a new A here as well A a new A 为什么这给出
  • 链表相对于数组有什么优点,反之亦然?

    请解释一下链表相对于数组的优点是什么 与链表相比 使用数组有什么优点吗 问候 舒阿布 两者都存储元素序列 但使用不同的技术 An array将元素按连续顺序存储在内存中 即如下所示 item 1 item 2 item 3 item x h
  • node_modules/@firebase/firestore/dist/index.d.ts:27:28 中出现错误 - 错误 TS1005:预期为“]”

    我尝试将 firebase 包含到我的角度应用程序中 我导入了所有内容 但是当我运行时ng serve我收到此错误 ERROR in node modules firebase firestore dist index d ts 27 28
  • 如何解决头文件中的变量冲突?

    我正在 OpenSees 一个主要用 Visual Studio C 编写的开源地震工程模拟项目 中编写自适应步长更新算法 我面临两个不同头文件中具有相同名称的两个变量之间的冲突 即windef h and 钢Z01 h 我需要一种方法来解
  • Highcharts xAxis 钻取未正确更改

    http jsfiddle net ZBXV7 2 http jsfiddle net ZBXV7 2 when I click a column or label the xAxis write incorrect label but t
  • JUnit 中的失败和错误有什么区别?

    我在大型代码库上运行 JUnit 测试 并且我已经意识到有时会收到 错误 而有时会收到 失败 有什么不同 Failures are when your test cases fail 即你的断言是不正确的 Errors are when u
  • 什么时候适合使用 extern 关键字而不使用 [DllImport] 属性?

    今天我重新阅读一些 Net 文档时 我注意到该文档的第一部分extern关键词文档 https msdn microsoft com en us library e59b22c5 aspx claims extern 修饰符用于声明外部实现