Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to add C++ library in a .NET Core project

Tags:

c++

.net-core

dll

How is the way to add a C++ Library in a .NET Core project (Class Library). I tried creating a nuget package but doesn't work. I got this error:

An unhandled exception of type 'System.DllNotFoundException' occurred in "NameOfDll.dll"

When I add the nuget package the project.json add the following reference:

  "dependencies": {
    "Core": "1.0.0-*",
    "NETStandard.Library": "1.6.0",
    "NameOfDll.dll": "1.0.0"
  },
like image 902
gemr1423 Avatar asked Sep 07 '16 19:09

gemr1423


Video Answer


2 Answers

dependencies attribute in project.json specifies package dependencies, because of this NuGet handles NameOfDll.dll as a package ID, but not as a dll name.

To add native C++ dlls into you NuGet package for .xproj library you should do the following steps:

  1. Put your NameOfDll.dll in \lib directory near MyClassLibrary.xproj
  2. Open project.json file and add there:

    "packOptions": {
      "files" : {
        "includeFiles" : "lib/NameOfDll.dll"
      }
    }
    
  3. Execute dotnet pack

NameOfDll.dll will be included into NuGet package under the path lib\NameOfDll.dll.

To add native C++ dlls into your NuGet package for .csproj library you should do the following steps:

  1. I assume you have managed project with name MyClassLibrary.csproj.
  2. Create new NuGet package for you class library with nuget spec command.
  3. Create \lib, \build, \content and \tools directories near MyClassLibrary.nuspec.
  4. Copy all your native dlls into the \build folder.
  5. Change extension of copied native dlls to .native.
  6. Create MyClassLibrary.targets with the following content inside \build folder:

    <?xml version="1.0" encoding="utf-8"?>
    <Project ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
      <ItemGroup>
        <AvailableItemName Include="NativeBinary" />
      </ItemGroup>
      <ItemGroup>
        <NativeBinary Include="$(MSBuildThisFileDirectory)*">
          <TargetPath></TargetPath>
        </NativeBinary>
      </ItemGroup>
      <PropertyGroup>
        <PrepareForRunDependsOn>
          $(PrepareForRunDependsOn);
          CopyNativeBinaries
        </PrepareForRunDependsOn>
      </PropertyGroup>
      <Target Name="CopyNativeBinaries" DependsOnTargets="CopyFilesToOutputDirectory">
        <Copy SourceFiles="@(NativeBinary)"
              DestinationFiles="@(NativeBinary->'$(OutDir)\%(TargetPath)\%(Filename).dll')"
              Condition="'%(Extension)'=='.native'">
          <Output TaskParameter="DestinationFiles" ItemName="FileWrites" />
        </Copy>
        <Copy SourceFiles="@(NativeBinary)"
              DestinationFiles="@(NativeBinary->'$(OutDir)\%(TargetPath)\%(Filename).%(Extension)')"
              Condition="'%(Extension)'!='.native'">
          <Output TaskParameter="DestinationFiles" ItemName="FileWrites" />
        </Copy>
      </Target>
    </Project>
    

    Hint: The .targets content is taken from this question. The above .targets file will be injected on an installation of the NuGet package into the target project file.

  7. Add the following lines into your MyClassLibrary.nuspec:

    <files>
      <file src="lib\" target="lib" />
      <file src="tools\" target="tools" />
      <file src="content\" target="content" />
      <file src="build\" target="build" />
    </files>
    
  8. Execute nuget pack MyClassLibrary.csproj to build your NuGet package.

like image 56
Nikita Avatar answered Oct 15 '22 04:10

Nikita


Here is a one-click way to do it in .net core 2. I used it in my website and it works.

Right click your project in Solution Explorer, select Add->Existing Item, browse and choose your dll (select show all extensions). Then your dll will appear in Solution explorer.

In the Solution Explorer, right-click your dll -> Properties. Set build action: Content, and Copy to Output Directory: Copy if newer (or always copy).

It's done. Use your dll in your code staightforward like this:

[DllImport("my_dll.dll", CallingConvention = CallingConvention.Cdecl)]

like image 34
Serena Yu Avatar answered Oct 15 '22 05:10

Serena Yu