使用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可能无法导入或如何绕过它? 我已经尝试将其添加为内容...不确定这是否正确。
答案 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中导入它并通过执行这些步骤来使用它:
References -> Add Reference -> COM -> your.dll
答案 3 :(得分:0)
[DllImport]属性是"指向" .dll上的.cs文件。您不需要添加任何引用或注册任何DLL或执行任何操作,除了在项目中包含.cs文件并确保.dll文件在您运行它时位于项目的bin文件夹中。 - 科尔坎贝尔