添加.dll作为引用.无法理解错误消息

本文关键字:错误 消息 dll 引用 添加 | 更新日期: 2023-09-27 17:57:04

使用Visual Studio 2008和Xna 3.1,我得到了一个硬件"Mindwave",它的所有代码都包含在一个.dll文件中。我有一个 ThinkGear.cs 文件,它只是一个包装类,它引用.dll文件中的所有内容,其代码如下:

[DllImport("ThinkGear")]
public static extern int
    TG_GetDriverVersion();

评论中给出的描述是这样的:

这个用于 C# 的 ThinkGear

类只是一个精简接口层,它使用 InteropServices 提供对 TGCD 库中 API 函数的访问,允许 C# 程序使用 TGCD 与 ThinkGear 模块进行通信。

当我将.dll文件作为引用添加到项目中时,我收到此错误消息。

无法添加对"C:''thinkgear.dll"的引用。请确保该文件可访问,并且它是有效的程序集或 COM 组件。

有谁知道为什么 dll 可能不会导入或如何绕过它?我试过将其添加为内容...不确定这是否是正确的方向。

添加.dll作为引用.无法理解错误消息

在 .NET 中,

项目引用必须是程序集,在 .NET 术语中,这表示托管库或可执行文件。 您看到的错误消息是由于您尝试添加对非托管库(不是程序集)的引用。

.NET Framework 可以使用平台调用服务调用非托管库,通常以其缩写名称 P/Invoke 而闻名。 包装器代码中的DllImportAttribute是平台调用服务的一部分。

看看你发布的函数调用:

[DllImport("ThinkGear")]
public static extern int TG_GetDriverVersion();

请注意extern关键字。 在 C# 中,extern 表示函数的主体在当前程序集之外的某个位置定义。 外面在哪里? 这就是DllImport属性的用途。 所以这个函数声明是说,"有一个名为 TG_GetDriverVersion 的函数,它不带参数并返回一个int,但我不打算为你定义这个函数;如果你想要它的完整定义,去找非托管库'ThinkGear'并在那里看看。

编译器不需要引用来解析此方法,因为您已向其附加了一个注释,上面写着"不要担心它的实际来源;我告诉你它是什么,所以只需按照我声明的方式使用它,并假设它可以在运行时访问。

当您执行应用程序并尝试调用TG_GetDriverVersion()时,CLR 会看到您已使用 extern 标记它,检查 DllImport 属性以查看哪个库包含实际代码,在硬盘驱动器中搜索有问题的库(在本例中为 ThinkGear.dll),将该库加载到进程中,在库中查找相应的函数, 并调用它。

只要 CLR 能够找到有问题的库,这应该都"正常工作"。 因此,您需要做的就是确保应用程序的 bin 目录中存在正确的库,否则,CLR 在尝试调用函数时将引发运行时异常。

[DllImport]仅用于与非托管(非 COM)DLL 通信。 如果您的 DLL 是非托管的,则无法将其添加为引用。 如果 DLL 是托管的,则不需要 [DllImport] 语句。

1) 您确定此 DLL 具有非托管代码吗? 如果没有,您可以安全地删除[DllImport]语句

2) 如果它是非托管的,则必须添加构建步骤以将非托管 DLL 复制到 bin/debug 或 bin/release 目录中。 您不能通过引用添加此 dll! 有关执行此操作作为生成后步骤的详细信息,请参阅使用生成后事件将文件从一个项目复制到另一个项目...VS2010.

如果您使用的是非托管 DLL,我建议您围绕它创建一个托管包装类,这样您就不必用不安全的调用污染整个代码库。

我的

一个DLL遇到了同样的问题,尽管它是一个borland c ++ DLL,我没有关于它的源代码。我能够在VS中导入它并通过执行以下步骤使用它:

  1. 使用 regsvr32 注册 DLL
  2. 导入DLL,您将以在Visual Studio中执行的正常方式获得:References -> Add Reference -> COM -> your.dll
  3. 现在,您应该能够调用函数。

[DllImport] 属性是将.cs文件"指向".dll的属性。除了在项目中包括.cs文件并确保.dll文件在运行时位于项目的 bin 文件夹中之外,无需添加任何引用或注册任何 DLL 或执行任何操作。- 科尔坎贝尔