C# 在 Mono 中使用预编译的 .NET 程序集 DLL?
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/1160722/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
Using Precompiled .NET Assembly DLL in Mono?
提问by NickAldwin
We're currently testing Mono to see if our .NET DLLs will work for customers on Linux. Our DLLs provide components for Windows Forms. I placed the DLLs in the Debug directory, added the references, and created a class deriving from a Windows Form. The class had run fine standalone, but after I added the DLL references and created one of our components (the intellisense worked fine), it compiles but will not run:
我们目前正在测试 Mono 以查看我们的 .NET DLL 是否适用于 Linux 上的客户。我们的 DLL 为 Windows 窗体提供组件。我将 DLL 放在 Debug 目录中,添加了引用,并创建了一个派生自 Windows 窗体的类。该类独立运行良好,但在我添加 DLL 引用并创建我们的组件之一(智能感知工作正常)后,它编译但不会运行:
** (/home/aldwin/testMonoWF/testMonoWF/bin/Debug/testMonoWF.exe:26905): WARNING **: Could not load file or assembly 'OUR.ASSEMBLY, Version=1.0.0.1, Culture=neutral, PublicKeyToken=ATOKEN' or one of its dependencies. Unhandled Exception: System.IO.FileNotFoundException: Could not load file or assembly 'OUR.ASSEMBLY, Version=1.0.0.1, Culture=neutral, PublicKeyToken=ATOKEN' or one of its dependencies. File name: 'OUR.ASSEMBLY, Version=1.0.0.1, Culture=neutral, PublicKeyToken=ATOKEN'
I looked at the properties of the assembly, and it is that version with that public key.
我查看了程序集的属性,它是具有该公钥的版本。
Is there a way for me to use these DLLs? What am I doing wrong?
有没有办法让我使用这些 DLL?我究竟做错了什么?
EDIT:
编辑:
According to MoMA, other than some [MonoTodo]s that have no bearing on the situation, there is one problem in three of the DLLs:
根据 MoMA 的说法,除了一些与情况无关的 [MonoTodo] 之外,其中三个 DLL 存在一个问题:
Calling Method | P/Invoke Method | P/Invoke Library void OnHandleCreated (EventArgs) | int GoText/ComboBoxControl.SetWindowTheme (IntPtr, string, string) | uxtheme.dll
However, I opened one of our sample projects created with VS2008, pointed the reference to the DLL at the right place, and it worked fine. But I could not get the reference to work in a new project. Am I doing something wrong?
但是,我打开了用 VS2008 创建的示例项目之一,将 DLL 的引用指向了正确的位置,并且运行良好。但是我无法获得在新项目中工作的参考。难道我做错了什么?
EDIT 2: To clarify, we don't want to recreate an existing windows application - we are simulating a customer creating a new application with our dll. I was just testing that to see if it was a dll problem. Since the VS-made application was able to find the dll and run successfully, it would seem it's not a dll problem. The new application is not calling anything the VS-created application doesn't.
编辑 2:澄清一下,我们不想重新创建现有的 Windows 应用程序 - 我们正在模拟客户使用我们的 dll 创建一个新应用程序。我只是在测试它是否是一个dll问题。由于VS制作的应用程序能够找到dll并成功运行,因此看起来不是dll问题。新应用程序不会调用 VS 创建的应用程序不会调用的任何内容。
回答by Jon Galloway
I'd test the DLL with MOMA (Mono Migration Analyzer)to see if it's using unsupported API's.
我会用MOMA(单声道迁移分析器)测试 DLL,看看它是否使用了不受支持的 API。
回答by jpobst
You can generally get more details on .dll loading errors by running with:
您通常可以通过运行以下命令获取有关 .dll 加载错误的更多详细信息:
MONO_LOG_LEVEL="debug" MONO_LOG_MASK="dll" mono myapp.exe
MONO_LOG_LEVEL="调试" MONO_LOG_MASK="dll" 单声道 myapp.exe
回答by miguel.de.icaza
What Jonathan said is correct, you need to run the command as shown and it will produce copious amounts of information.
乔纳森说的是正确的,你需要运行如图所示的命令,它会产生大量的信息。
The assembly has a strong name, so it sounds like on Windows you have a dependency that is installed on the GAC. If "OUR.ASSEMBLY" is supposed to be there, run:
该程序集具有强名称,因此听起来在 Windows 上您有一个安装在 GAC 上的依赖项。如果“OUR.ASSEMBLY”应该在那里,请运行:
gacutil -i OUR.ASSEMBLY.dll
gacutil -i OUR.ASSEMBLY.dll
To install it. There might be other dependencies that OUR.ASSEMBLY.dll needs which is what JPobst' command would show.
安装它。可能还有 OUR.ASSEMBLY.dll 需要的其他依赖项,这就是 JPobst' 命令将显示的内容。
回答by lupus
The likely issues are that the assembly is not put in the same directory as the program or that the case sensitivity of the assembly file name is not preserved when it was copied. For example, you may have a OUR.ASSEMLY reference, but the filename is OurAssembly.DlL or any other invalid case combination that people can come up with.
可能的问题是程序集未与程序放在同一目录中,或者程序集文件名在复制时不区分大小写。例如,您可能有一个 OUR.ASSEMLY 引用,但文件名是 OurAssembly.DlL 或人们可以想出的任何其他无效大小写组合。
回答by onitake
uxtheme.dll
is the Windows theme engine, if I'm not mistaken. It's quite natural you don't have that in a non-Windows environment, so P/Invoking its exported functions is not directly possible.
uxtheme.dll
是 Windows 主题引擎,如果我没记错的话。在非 Windows 环境中没有它是很自然的,因此 P/Invoking 其导出的函数是不可能直接实现的。
You have two options here:
您在这里有两个选择:
- Open up that
OnHandleCreated
method and replace theSetWindowTheme
call with something portable or - Create a dummy
libuxtheme.so
that contains just this one function so mono can P/Invoke it.
- 打开该
OnHandleCreated
方法并用SetWindowTheme
可移植的或 - 创建一个
libuxtheme.so
只包含这个函数的虚拟对象,以便单声道可以 P/Invoke 它。
I recommend the first approach if possible, as you'd need to create that dummy libuxtheme.so
for every platform you're supporting. I.e., you'd have to make a libuxtheme.so
for x86 Linux, a libuxtheme.so
for x86_64 Linux, the same for FreeBSD, a libuxtheme.dylib
for Mac OS X and so on.
如果可能,我建议使用第一种方法,因为您需要为libuxtheme.so
您支持的每个平台创建该虚拟对象。即,您必须libuxtheme.so
为 x86 Linux制作一个,libuxtheme.so
为 x86_64 Linux制作一个,为 FreeBSD 制作一个,libuxtheme.dylib
为 Mac OS X 制作一个等等。
If OnHandleCreated
was generated by some UI designer or the like, you probably have to remove some widget themes the get rid of the call.
如果OnHandleCreated
是由一些 UI 设计师或类似的人生成的,您可能必须删除一些小部件主题才能摆脱调用。