【问题标题】:Unmanaged Exports: Cannot compile assembly非托管导出:无法编译程序集
【发布时间】:2010-01-11 16:36:53
【问题描述】:

我想创建一个可以从非托管代码 (Delphi 5) 访问的 .NET 程序集。

我找到了Unmanaged Exports 并按照那里的步骤操作,但我什至无法成功编译基本示例:

using RGiesecke.DllExport;

namespace DelphiNET
{
    public class Class1
    {
        [DllExport("add")]
        public static int Add(int left, int right)
        {
            return left + right;
        }
    }
}

DelphiNET.csproj项目文件:

...
<ItemGroup>
  <Compile Include="Class1.cs" />
  <Compile Include="DllExport\DllExportAttribute.cs" />
  <Compile Include="Properties\AssemblyInfo.cs" />
</ItemGroup>
<Import Project="$(MSBuildToolsPath)\Microsoft.CSharp.targets" />
<Import Project="DllExport\RGiesecke.DllExport.targets" />
...

这是错误:

------ Build started: Project: DelphiNET, Configuration: Release Any CPU ------
c:\WINDOWS\Microsoft.NET\Framework\v3.5\Csc.exe /noconfig /nowarn:1701,1702 /errorreport:prompt /warn:4 /define:TRACE /debug:pdbonly /filealign:512 /optimize+ /out:obj\Release\DelphiNET.dll /target:library Class1.cs DllExport\DllExportAttribute.cs Properties\AssemblyInfo.cs

Compile complete -- 0 errors, 0 warnings
DelphiNET -> C:\DelphiNET\bin\Release\DelphiNET.dll
ILDasm: calling 'C:\Program Files\Microsoft SDKs\Windows\v6.0A\Bin\ildasm.exe' with /quoteallnames /nobar "/out:C:\Documents and Settings\Lukas\Local Settings\Temp\tmp29F\DelphiNET.il" "C:\DelphiNET\bin\Release\DelphiNET.dll"
C:\DelphiNET\bin\Release\DelphiNET.dll : warning EXP0009: Platform is AnyCpu, generating creating binaries for each CPU platform in a separate folder...
ILAsm: calling 'c:\WINDOWS\Microsoft.NET\Framework\v2.0.50727\ILAsm.exe' with /nologo "/out:C:\DelphiNET\bin\Release\x86\DelphiNET.dll" "C:\Documents and Settings\Lukas\Local Settings\Temp\tmp29F\DelphiNET.x86.il" /DLL "/resource=C:\Documents and Settings\Lukas\Local Settings\Temp\tmp29F\DelphiNET.res"  /optimize  
C:\DelphiNET\DllExport\RGiesecke.DllExport.targets(8,5): error : 
C:\DelphiNET\DllExport\RGiesecke.DllExport.targets(8,5): error : Assembling 'C:\Documents and Settings\Lukas\Local Settings\Temp\tmp29F\DelphiNET.x86.il'  to DLL --> 'C:\DelphiNET\bin\Release\x86\DelphiNET.dll'
C:\DelphiNET\DllExport\RGiesecke.DllExport.targets(8,5): error : Source file is ANSI
C:\DelphiNET\DllExport\RGiesecke.DllExport.targets(8,5): error : 
C:\DelphiNET\DllExport\RGiesecke.DllExport.targets(8,5): error : Assembled method RGiesecke.DllExport.DllExportAttribute::.ctor
C:\DelphiNET\DllExport\RGiesecke.DllExport.targets(8,5): error : Assembled method RGiesecke.DllExport.DllExportAttribute::.ctor
C:\DelphiNET\DllExport\RGiesecke.DllExport.targets(8,5): error : Assembled method RGiesecke.DllExport.DllExportAttribute::.ctor
C:\DelphiNET\DllExport\RGiesecke.DllExport.targets(8,5): error : Assembled method RGiesecke.DllExport.DllExportAttribute::get_CallingConvention
C:\DelphiNET\DllExport\RGiesecke.DllExport.targets(8,5): error : Assembled method RGiesecke.DllExport.DllExportAttribute::set_CallingConvention
C:\DelphiNET\DllExport\RGiesecke.DllExport.targets(8,5): error : Assembled method RGiesecke.DllExport.DllExportAttribute::get_ExportName
C:\DelphiNET\DllExport\RGiesecke.DllExport.targets(8,5): error : Assembled method RGiesecke.DllExport.DllExportAttribute::set_ExportName
C:\DelphiNET\DllExport\RGiesecke.DllExport.targets(8,5): error : 
C:\DelphiNET\DllExport\RGiesecke.DllExport.targets(8,5): error : ***** FAILURE ***** 
C:\DelphiNET\DllExport\RGiesecke.DllExport.targets(8,5): error : 
Done building project "DelphiNET.csproj" -- FAILED.
========== Build: 0 succeeded or up-to-date, 1 failed, 0 skipped ==========

操作系统:WinXPSP3、Microsoft Visual C# 2008 Express Edition with SP1、.NET 3.5 SP1

知道有什么问题吗?谢谢。


编辑 23:40:

我发现了错误。它在函数的名称中 - addAdd 太相同了。当您更改其中一个时,它会起作用。

【问题讨论】:

  • 您是否尝试过仅使用 x86 或 x64 而不是 AnyCPU?
  • 这应该不是问题。在这种情况下,它会保持原始程序集不变,但会为 x86 和 x64 版本创建子文件夹。
  • 在我看来,它将来自 ilasm.exe 的诊断输出视为错误。
  • “***** FAILURE *****”部分来自 ILAsm。
  • 罗伯特,我遇到了类似的问题,你能帮忙吗? stackoverflow.com/questions/7264130/…

标签: .net delphi dll unmanaged


【解决方案1】:

顺便说一下,我刚刚更新了存档。 当您改用this 时,您甚至可以为您安排好一切。

这是一个项目模板,可以设置所有内容并且应该可以正常工作。

我确实在之前的版本中发现了一些要点,其中我做了一些并不总是正确的假设。 我之前实现的一个潜在问题是用于发布配置的 /optimize 开关。在这种情况下,有时 ILAsm 会卡在 IL 上,我还没有在新版本中看到这种情况。

【讨论】:

  • +1 好东西!您是否为此使用了 Brian Long 的文章(blong.com/Articles/DotNetInteropD8/Interop1/…blong.com/Conferences/BorConUK2002/Interop1/…)?
  • 不,但我确实看到不时提到这样的事情,所以我知道这是可能的,并试图让它透明地工作。我使用“.Net 2.0 IL Assembler”一书来确保我最终没有做任何货物崇拜的事情。 ;-)
  • 这是一个非常好的巧合 :-) 该模板不适用于 WinXp SP3 上的 Visual Studion 2008 Express SP1,但它适用于 Windows 7 64 位上的 VS 2010 beta 2(机器人在 VirtualBox 中运行)
  • 抱歉,不太了解 Express 版本。难道他们使用其他文件夹?您可以创建一个简单的项目并单击“文件/导出模板”将打开的项目导出为模板吗?它最终在哪个文件夹中?
  • IKVM.Reflection 现在支持exporting static managed methods as unmanaged DLL exports;应该可以使用它的高级 API 而不是 ILDasm。
【解决方案2】:

以防万一有人遇到同样的问题...

我这边的一些错误:

文件:DllExportAttribute.cs

public CallingConvention CallingConvention { get; set; }
public string ExportName { get; set; }

文件:$projectname$.csproj

<Import Project="$(MSBuildToolsPath)\Microsoft.CSharp.targets"/>  <!-- not working -->
<!-- change to -->
<Import Project="$(MSBuildBinPath)\Microsoft.CSharp.targets"/> <!-- working -->

这些很容易修复。

这是一个非常严重的问题。从生成的 \x86\MyDll.dll 制作 implib - lib 中的 dll 名称更改为 \MyDll.dll ...您可以制作 tdump MyDll.dll 并将进入导出部分“\MyDll.dll”而不是“MyDll .dll”。

由于这个问题,使用结果库的软件无法找到 dll...在我的情况下,它只能在 c:\MyDll.dll 中找到

通过在初始库上创建“coff2omf -lib:ca MyDll.lib”解决。但在那之前花了一天时间寻找解决方案...

【讨论】:

    【解决方案3】:

    导出名称为“add”的 [DllExport("...)] 似乎会引发错误,与“sub”相同。 来自 ilasm 的 vs 2010 中的消息是“将文件名组装到 dll ......源文件是 UNICODE”。

    感谢您的出色工作!

    【讨论】:

      【解决方案4】:

      如果有人也遇到过,我在导出函数时也遇到了这个错误 名称是“init”,因此更改名称可以解决问题。

      所以这会产生这样的错误:

      [DllExport("init")]

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2012-01-24
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2013-12-15
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多