添加.dll作为参考。无法理解错误消息

时间:2014-04-07 14:01:00

标签: c# visual-studio visual-studio-2008 dll xna

使用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可能无法导入或如何绕过它? 我已经尝试将其添加为内容...不确定这是否正确。

4 个答案:

答案 0 :(得分:3)

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

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

看一下你发布的函数调用:

[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将在尝试调用该函数时抛出运行时异常。

答案 1 :(得分:2)

[DllImport]仅用于与非托管(非COM)dll交谈。如果您的DLL不受管理,则无法将其添加为参考。如果您的DLL是托管的,则不需要[DllImport]语句。

1)你确定这个DLL有非托管代码吗?如果没有,您可以安全地删除[DllImport]声明

2)如果它不受管理,则必须添加构建步骤以将非托管DLL复制到bin / debug或bin / release目录中。你不能通过参考添加这个DLL!有关将此作为构建后步骤执行此操作的详细信息,请参阅Copy file(s) from one project to another using post build event...VS2010

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

答案 2 :(得分:0)

我的DLL有一个相同的问题,虽然它是一个borland c ++ DLL而且我没有关于它的源代码。我能够在VS中导入它并通过执行这些步骤来使用它:

  1. 使用regsvr32
  2. 注册您的DLL
  3. 导入DLL,您将获得在Visual Studio中执行此操作的常规方法:References -> Add Reference -> COM -> your.dll
  4. 现在,您应该能够调用您的功能。

答案 3 :(得分:0)

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