在WinForms应用程序中使用外部DLL需要哪种配置?

时间:2011-09-23 15:29:39

标签: c# entity-framework-4 interop oracle11g dllimport

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

错误说:

  

“找不到DLL库函数。检查注册表安装路径。”

所有执行都是在调试模式下完成的。 我比较了两个项目的配置。最相关的区别是Test项目面向Any CPU和WinForms app只指向x86。

它可能是什么?

更新

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

3 个答案:

答案 0 :(得分:1)

我有一个理论。

让我们假设以下情况:

  • ocr.dll依赖于其他一些本机DLL,我们称之为 other.dll [A]
  • 您的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] 和东西migh神奇地开始工作。
  • 尝试使用其他版本的ADO.NET提供程序。
  • 尝试其他ADO.NET提供程序。
  • 尝试从您的供应商处获取静态链接的ocr.dll(即,对 other.dll [A] 没有运行时依赖性)。

答案 1 :(得分:0)

因此,对DLL的调用只能从一个按钮进行,但它不能从复杂的形式开始工作。我会说有一个未定义的行为正在发生。问题仍然是你,是不是写错误的编组,还是写得不好的DLL。

由于我们无法访问DLL的源代码,您可以发布函数的原型,所有相关的结构定义以及您为其编写的DllImport行吗?

答案 2 :(得分:0)

Google无法找到错误消息,这意味着(不是绝对:) :)它不是系统消息,而是来自dll代码的自定义消息。所以dll做了一些狡猾的事情。我想它会尝试在内部将你的调用加到另一个函数。

我建议你尝试一些事情:

  • 运行x86配置。在项目属性中 - > “构建”选项卡将平台设置为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%。