我需要在WinForms应用程序中使用外部DLL的哪个配置
本文关键字:DLL 外部 配置 WinForms 应用程序 | 更新日期: 2023-09-27 18:09:41
我正在使用外部DLL使用我编写的包装器来消费OCR设备。我对包装器进行了测试,效果很好。但是,当我使用WinForms项目来消费包装器的客户端类(位于另一个项目)时,在调用从DLL(使用[DLLImport(...)]
)导入的c#方法时出现错误,说DLL未注册。
错误提示:
"没有找到DLL库函数。"检查注册表安装路径。"
所有的执行都是在调试模式下进行的。我比较了两个项目的配置。最相关的区别是,测试项目是面向任何CPU和WinForms应用程序只指向x86。
会是什么呢?
- 我已经尝试使用
Regsvr32.exe
注册dll,但它没有工作。我想过使用Gacutil.exe
,但它需要卸载。net框架1.1以外的所有框架… - 我想知道…在测试环境中,可能一切都运行良好,因为测试框架有它的dll或可执行文件(或类似的东西)完全注册在windows中,所以那些是可信的dll。调试生成的dll可能不受windows信任,因此出现此问题?
- 我在同一个令人不安的项目中创建了一个表单,然后我从我添加到它的按钮调用OCRWrapper。OCR起作用了!不幸的是,重写第一种形式是很困难的,因为我们已经在它上面投入了很多时间;所以,我仍然想知道我需要改变什么麻烦的形式…
- 我重新开始从头开始表单的开发,并添加了所有与之相关的组件;一切工作正常,OCR读取成功的所有数据。当我使用调用
ObjectContext
加载组合框并再次出现错误时……我使用的实体框架连接到Oracle。
我有一个理论。
让我们想象一下下面的情况:
- ocr.dll依赖于一些其他的本地DLL,我们叫它other. DLL [A]。
- 如果这是一个静态依赖,你可以通过dependency Walker看到它。如果它是动态的,你可以使用Sysinternals Process Explorer在运行时监视工作测试项目中的DLL加载。
- ADO。.NET提供程序在底层使用本机DLL(这对于ODP.NET来说当然是正确的),它依赖于other.dll [B],与other.dll [a]相比,它恰好具有相同的名称,但实际上是不同的DLL(或至少是不同的版本)。
那么,在运行时,这可能会发生:
- 当您连接到数据库时,ADO。. NET提供程序动态加载其本机dll,包括other.dll [B]. 然后你尝试从OCR DLL调用一个函数。P/Invoke尝试动态加载OCR DLL并成功,但是other.dll [B]已经加载,OCR . DLL试图从它中使用一些函数,而不是从other.dll [A]实际存在的地方。
欢迎来到DLL地狱。那么你能做些什么呢?
- 尝试改变调用ocr.dll和ADO的顺序。. NET提供程序以查看任何更改。如果你(非常)幸运,other.dll [A]可能实际上是一个新版本,仍然向后兼容other.dll [B],事情可能神奇地开始工作。
- 尝试其他版本的ADO。净提供者。 尝试另一个ADO。净提供者。
- 尝试从您的供应商获得静态链接的ocr.dll(即没有运行时依赖于other.dll [a])。
因此,对DLL的调用从单个按钮起作用,但不能从复杂的表单起作用。我得说这是一种未定义的行为。问题仍然是,是您错误地编写了封送,还是DLL编写得很糟糕。
既然我们不能访问DLL的源代码,也许你可以发布函数的原型,所有相关的结构定义,以及你为它写的DllImport行?
Google找不到这个错误消息,这意味着(不是绝对的,虽然:))它不是系统消息,而是来自dll中的代码的自定义消息。所以dll做了一些不可靠的事情。我猜它试图在内部双重分派你对另一个函数的调用。
我建议你做几件事:
-
运行x86配置。在项目属性-> Build选项卡中,将平台设置为x86。这是假设DLL是一个x86 DLL。
dumpbin/headers orc.dll
File Type: DLL FILE HEADER VALUES 14C machine (**x86**) 4 number of sections 4CE7B6FC time date stamp Sat Nov 20 11:54:36 2010 0 file pointer to symbol table 0 number of symbols E0 size of optional header 2102 characteristics Executable 32 bit word machine DLL
这个命令行应该告诉您比特数。如果它是64位运行64位配置,但我打赌它是32位的。
- 不要在项目中包含dll。我猜你已经这么做了。确保dll位于%PATH%环境变量下的文件夹中。当你在命令提示符下运行这个命令时:
, ocr.dll
应该告诉您DLL在哪里。如果没有,则将安装dll的文件夹添加到%PATH%。