我需要在WinForms应用程序中使用外部DLL的哪个配置

本文关键字:DLL 外部 配置 WinForms 应用程序 | 更新日期: 2023-09-27 18:09:41

我正在使用外部DLL使用我编写的包装器来消费OCR设备。我对包装器进行了测试,效果很好。但是,当我使用WinForms项目来消费包装器的客户端类(位于另一个项目)时,在调用从DLL(使用[DLLImport(...)])导入的c#方法时出现错误,说DLL未注册。

错误提示:

"没有找到DLL库函数。"检查注册表安装路径。"

所有的执行都是在调试模式下进行的。我比较了两个项目的配置。最相关的区别是,测试项目是面向任何CPU和WinForms应用程序只指向x86。

会是什么呢?

  1. 我已经尝试使用Regsvr32.exe注册dll,但它没有工作。我想过使用Gacutil.exe,但它需要卸载。net框架1.1以外的所有框架…
  2. 我想知道…在测试环境中,可能一切都运行良好,因为测试框架有它的dll或可执行文件(或类似的东西)完全注册在windows中,所以那些是可信的dll。调试生成的dll可能不受windows信任,因此出现此问题?
  3. 我在同一个令人不安的项目中创建了一个表单,然后我从我添加到它的按钮调用OCRWrapper。OCR起作用了!不幸的是,重写第一种形式是很困难的,因为我们已经在它上面投入了很多时间;所以,我仍然想知道我需要改变什么麻烦的形式…
  4. 我重新开始从头开始表单的开发,并添加了所有与之相关的组件;一切工作正常,OCR读取成功的所有数据。当我使用调用ObjectContext加载组合框并再次出现错误时……我使用的实体框架连接到Oracle。

我需要在WinForms应用程序中使用外部DLL的哪个配置

我有一个理论。

让我们想象一下下面的情况:

  • 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%。