我需要在WinForms应用程序中使用外部DLL的哪个配置?
我正在使用外部DLL来使用我写的包装器来使用OCR设备。我已经对包装进行了测试,并且完美地工作。但是,当我使用WinForms项目来使用包装程序的客户机类(位于另一个项目中)时,调用从DLL导入的C#方法(使用[DLLImport(...)]
)说该DLL未注册时出现错误。我需要在WinForms应用程序中使用外部DLL的哪个配置?
错误说:
“DLL库函数没有发现检查注册表中的安装路径。”
所有执行都在调试模式下完成。 我比较了两个项目的配置。最相关的区别是Test项目面向任何CPU,而WinForms应用程序只指向x86。
什么可能呢?
更新
- 我试图注册使用
Regsvr32.exe
的DLL,但没有奏效。我想过使用Gacutil.exe
但是卸载以后的.NET Framework 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],这恰好具有相同的名称,但实际上是一个不同的DLL(或至少不同的版本)相比other.dll [A]。
然后,在运行时,这可能会发生:
- 当您连接到数据库,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.NET提供程序。
- 尝试另一个ADO.NET提供程序。
- 尝试从供应商处获得一个静态链接的ocr.dll(即没有运行时依赖于other.dll [A])。
所以,在调用DLL从一个按钮的工作原理,但它不会从一个复杂的形式工作。我会说有一个未定义的行为正在进行。问题依然存在,无论是你,编写错误的编码,还是编写错误的DLL。
因为我们没有访问该DLL的源代码,也许你可以张贴函数的原型,以及所有相关结构的定义,以及您为它写了的DllImport线?
我不认为错误是由于它的OCR失败而造成的_only_当从特定窗体调用时...但是请看一看:[[DllImport( “aDll.dll”)] private static extern uint aMethod()','[DllImport(“aDll.dll”,CallingConvention = CallingConvention.Cdecl,CharSet = CharSet.Ansi)] private static extern string aMethod2(ulong aParameter);' ,'[DllImport(“aDll.dll”,CallingConvention = CallingConvention.Cdecl,CharSet = CharSet.Ansi)]'',私人静态不安全的外部超时aMethod3(参考IntPtr aParameter,ref IntPtr anotherParameter,ref IntPtr afterTheLastParameter);'。 – JPCF
我正在与一个隐私的DLL的安全业务我不能透露具体的细节。但签名像我写的[这里](http://*.com/questions/7515798/problem-at-marshalling-a-standard-c-string-to-ac-string),[这里] (http://*.com/questions/7423376/how-can-i-write-a-signature-on-c-for-a-wrapped-c-method-having-double-indirect)和[这里]( http://*.com/questions/7410382/how-can-i-write-a-signature-on-c-for-a-wrapped-c-method-having-a-pointer-to-a) – JPCF
什么你所做的很棘手......我刚刚看到其他的SO问题,我不太确定它们是否完全正确。我需要看到这些函数的C原型,并且可能使用它们的一些示例C代码。原型并不总是足够写一个适当的马歇尔,你需要行为信息。 – rodrigo
谷歌无法找到该错误消息,这意味着(不是绝对:)虽然它不是一个系统消息,但是一个自定义的来自在DLL中的代码。所以这个DLL会做一些狡猾的事情。我想它会尝试在你的内部调用另一个函数。
几件事我建议你试试:
-
运行的x86配置。在项目属性 - > Build选项卡中将平台设置为x86。这是假设该DLL是一个x86 dll。
DUMPBIN /头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%。
您是否在64位系统上运行? – stuartd
@StuartDunkeld英特尔核心2二重奏...我想这是一个64位系统,但是,虽然我GOOGLE了它,但我并没有确定... – JPCF
@HansPassant异常不是来自Visual Studio。 ..当我从de OCR中调用一个方法时(使用'[DLLImport]'标记的方法),返回的错误信息是'“找不到DLL Library函数。 – JPCF