Frage

Ich habe C # Wrapper-Code, dass Anrufe Funktionen von einem nativen (C ++) dll. Derzeit kann ich einen Verweis auf die C # DLL hinzufügen und haben die ‚Copy Local‘ Option auf true gesetzt. Doch die native DLL, die eine Abhängigkeit ist, kann nicht als Referenz hinzugefügt werden. - so gibt es keine Option ‚Copy Local‘ ist

Ich habe die folgenden Ansätze versucht,

  1. Mit Hilfe eines Post-Build-Ereignisse die native DLL aus dem Libs kopieren Ordner in den $(TargetFolder)

    copy "$(ProjectDir)Libs\NQuantLibc.dll" "$(TargetDir)NQuantLibc.dll"

  2. enthalten die native DLL als ein vorhandenes Element im Projekt (Add -> Existing Item -> Neue dll). Diese Option ermöglicht es mir, die ‚Copy Local‘ Option zu verwenden. Der Nachteil dieses Ansatzes ist, dass die DLL immer zeigt als Projektelement.

Ich habe auch versucht, „Alle Dateien anzeigen“, die mir erlaubt, um die Libs Ordner. Ich schließe dann die NQuantLibc.dll-Datei in dem Projekt, das mir die ‚Copy Local‘ Option abbinden. Allerdings gab das mir ein unerwartetes Ergebnis. Es entstand ein Libs Unterordner die DLL im Ordner bin enthält (zB bin/debug/Libs/NQuantLibc.dll). Nicht ideal, da die C # dll war nicht in der Lage, richtig die native DLL aufrufen, da sie nicht da war.

Die beiden oben genannten Optionen über Arbeit. Gibt es bessere Möglichkeiten, eine native DLL in den Ordner ist so zu kopieren, dass die Abhängigkeit wird immer gelöst werden? Alternativ gibt es einen anderen Ansatz, um diese Art von Szenario?

War es hilfreich?

Lösung

Verwenden von Project + Vorhandenes Element hinzufügen und die DLL auswählen. Wählen Sie die hinzugefügte Datei im Fenster Projektmappen-Explorer. Im Fenster Eigenschaften, die kopiert Output Directory-Einstellung „wenn neuere Kopie“ ändern.

Andere Tipps

Sie können die native DLL als verknüpftes Element hinzufügen, und die Verwendung " Kopieren, falls neuere ".
Das Problem mit nativer DLLs, ist, dass manchmal möchten Sie verschiedene DLLs verwenden, nach der Projektkonfiguration (Debug / Release oder Plattform).

Sie können das Projekt CSPROJ bearbeiten und verknüpfen die native DLL bedingt:

 <ItemGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|Win32' ">
    <Content Include="..\..\bin\Win32\Release\NQuantLibc.dll">
      <CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
    </Content>
 </ItemGroup>   
 <ItemGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|Win32' ">
    <Content Include="..\..\bin\Win32\Debug\NQuantLibc_d.dll">
      <CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
    </Content>
  </ItemGroup>
  <ItemGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|x64' ">
    <Content Include="..\..\bin\x64\Debug\NQuantLibc_d.dll">
      <CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
    </Content>
  </ItemGroup>
  <ItemGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|x64' ">
    <Content Include="..\..\bin\x64\Release\NQuantLibc.dll">
      <CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
    </Content>
  </ItemGroup>

Beachten Sie die Kopieroption ist auf PreserveNewest , das bedeutet "kopieren, wenn neuere".

Gefunden einen besseren Weg. Nuget kann .targets Dateien, Hexe gespeichert ist, in dem Build-Ordner des Pakets, in Ihr Projekt hinzufügen. Mit dieser Art und Weise können Sie bei jedem Build kopieren einige Dateien Ihres Pakets, wo immer Sie wollen. Im folgenden Beispiel habe ich einige nicht DotNet DLL in eine „Binaries“ -Ordner gespeichert. An jedem Build werden Sie prüft, ob DLLs bereits im Ausgabeordner ($ OutputPath Variable) kopiert und kopieren Sie sie, falls erforderlich.

Nuspec Inhalt:

<?xml version="1.0" encoding="utf-8"?>
<package xmlns="http://schemas.microsoft.com/packaging/2010/07/nuspec.xsd">
    <metadata>
        <id>Example</id>
        <version>1.0.0</version>
        <authors>Example</authors>
        <requireLicenseAcceptance>false</requireLicenseAcceptance>
        <description>Example</description>
    </metadata>
    <files>
        <file src="Non-DotNet.dll" target="binaries\Non-DotNet.dll" />
        <file src="DotNet.dll" target="lib\net40\DotNet.dll" />
        <file src="Example.targets" target="build\Example.targets" />
    </files>
</package>

Example.targets Inhalt:

<Project xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
    <Target Name="CopyBinaries" BeforeTargets="BeforeBuild">
        <CreateItem Include="$(MSBuildThisFileDirectory)..\binaries\**\*.*">
            <Output TaskParameter="Include" ItemName="PackageBinaries" /> 
        </CreateItem>

        <Copy SourceFiles="@(PackageBinaries)"
              DestinationFolder="$(OutputPath)"
              SkipUnchangedFiles="true"
              OverwriteReadOnlyFiles="true"
        />
    </Target>
</Project>

Fügen Sie die DLL als Datei im Projekt ( „Als Link“ vielleicht, wenn u will, dass es noch in einem anderen Verzeichnis befindet). Dann setzt die Build Action auf Inhalt und kopiert Ausgabeverzeichnis auf true gesetzt.

Wenn Sie OK mit dem erstellten „Libs“ -Ordner, können Sie versuchen, es auf das Pfad für Ihre Anwendung Sondieren, indem Sie den folgenden in der app.config Datei hinzufügen:

<configuration>
   <runtime>
      <assemblyBinding xmlns="urn:schemas-microsoft-com:asm.v1">
         <probing privatePath="Libs;Bin2"/>
      </assemblyBinding>
   </runtime>
</configuration>

Dies wird die Laufzeit zu sehen in allen angegebenen Verzeichnisse für die DLL verursachen.

Bearbeiten Leider ist dies wirkt sich nicht auf die nicht verwaltete DLL Laden von DllImport .

Anscheinend habe ich zufällig das gleiche Problem haben, aber ich wollte nicht, Projektdatei tun, so viel Bearbeitung, so dass ich folgende Post-Build-Skript am Ende mit:

xcopy /y "$(ProjectDir)\lib_$(Platform)\*.dll" "$(ProjectDir)$(OutDir)"

So stellen Sie sicher, dass Sie einen Ordner für jede Targeting-Plattform benötigt, z.B .: lib_x86, lib_x64 und vielleicht lib_AnyCPU

Lizenziert unter: CC-BY-SA mit Zuschreibung
Nicht verbunden mit StackOverflow
scroll top