Tri*_*fon 19 .net c++ visual-studio
我有一个混合模式C++项目,生成一个托管DLL程序集导出一些CLR类(称之为Managed.dll).这个项目使用的是原生dll(称之为Native.dll).
当我从另一个生成Client.exe的项目引用Managed.dll时,一切都按预期工作,除了我需要在与Client.exe相同的文件夹中手动复制Native.dll.
如果有办法说服VS本地复制(在Client.exe的bin文件夹中)不仅Managed.dll而且还有Native.dll?
我试图在清单中包含Native.dll作为依赖程序集,但这没有帮助.
编辑
Managed.dll将成为可再发行组件.它将安装在"C:\ Program Files ....."的文件夹中.当使用Visual Studio的开发人员添加对Managed.dll的引用时,还应将Native.dll复制到其项目的\ bin文件夹中.
neo*_*ope 11
有几种方法可以告诉VS将dll复制到目标文件夹:
1.添加dll作为项目的资源.如果dll更新,请告诉VS复制它
2.添加一个引用dll项目的新项目,并将OutDir设置为所需的文件夹.这个项目除了复制dll外什么都不做.
3.在vcxproj文件中使用PostBuildEvent
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
<ClCompile>
</ClCompile>
<Link>
</Link>
<PostBuildEvent>
<Command>
echo off
mkdir "$(ProjectDir)..\..\bin\$(Configuration)\"
copy "$(OutDir)xxx.dll" "$(ProjectDir)..\..\lib\$(Configuration)\"
echo on
</Command>
</PostBuildEvent>
</ItemDefinitionGroup>
Run Code Online (Sandbox Code Playgroud)
4.在vcxproj文件中使用PreBuildEvent
5.在vcxproj文件中使用CustomBuild
<ItemGroup>
<CustomBuild Include="..\..\xxx.dll">
<FileType>Document</FileType>
<Command>
call mkdir "$(OutDir)" 2>nul &
copy /Y "..\..\xxx.dll" "$(OutDir)xxx.dll"
</Command>
<Message>Copying xxx.dll to $(OutDir)\xxx.dll</Message>
<Outputs>$(OutDir)\xxx.dll</Outputs>
</CustomBuild>
</ItemGroup>
Run Code Online (Sandbox Code Playgroud)
6.使用makefile并在makefile中复制dll.并使用nmake来构建
7.编写执行复制作业的bat文件,并调用bat文件,如3-6所示
8.使用python这样的脚本,也可以从网上下载dll.并按照3-6调用py文件.
9.其他构建工具也可以提供帮助,例如gradle
10.使它成为NuGet插件
有时我只是写一个蝙蝠,然后手动执行蝙蝠.
更新01(Self extract dll示例):
1.添加本机dll作为托管dll的资源
2.添加此init()方法
using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Reflection;
using System.Security.Cryptography;
using System.Text;
using System.Threading.Tasks;
namespace DllSelfExtract
{
public class SelfExtract
{
public static void Init()
{
String managedDllPath = System.Reflection.Assembly.GetExecutingAssembly().CodeBase;
String nativeDllPath = managedDllPath.Replace("file:///", "").Replace("DllSelfExtract.DLL", "TestDll.dll");
if(!File.Exists(nativeDllPath))
{
Stream dllIn = Assembly.GetExecutingAssembly().GetManifestResourceStream("DllSelfExtract.TestDll.dll");
if (dllIn == null) return;
using (Stream outFile = File.Create(nativeDllPath))
{
const int sz = 4096;
byte[] buf = new byte[sz];
while (true)
{
int nRead = dllIn.Read(buf, 0, sz);
if (nRead < 1)
break;
outFile.Write(buf, 0, nRead);
}
}
}
//LoadLibrary Here
}
}
}
Run Code Online (Sandbox Code Playgroud)
3.在使用托管dll的项目中,首先调用init()方法
SelfExtract.Init();
Run Code Online (Sandbox Code Playgroud)
更新02(NuGet示例):
1.创建一个新的NuGet项目
2.将托管程序集放在/ lib目录中
3.将非托管共享库和相关文件放在/ build子目录中,并将所有非托管*.dll重命名为*.dl_
4.在/ build子目录中添加一个自定义.targets文件,其内容类似于以下内容:
<?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)'=='.dl_'">
<Output TaskParameter="DestinationFiles" ItemName="FileWrites" />
</Copy>
<Copy SourceFiles="@(NativeBinary)"
DestinationFiles="@(NativeBinary->'$(OutDir)\%(TargetPath)\%(Filename).%(Extension)')"
Condition="'%(Extension)'!='.dl_'">
<Output TaskParameter="DestinationFiles" ItemName="FileWrites" />
</Copy>
</Target>
</Project>
Run Code Online (Sandbox Code Playgroud)
5.在Package.nuspec中为build文件夹添加构建规则
<files>
<file src="lib\" target="lib" />
<file src="tools\" target="tools" />
<file src="content\" target="content" />
<file src="build\" target="build" />
</files>
Run Code Online (Sandbox Code Playgroud)
6.建立包
7.在你的另一个C#项目中,只需添加这个NuGet包.
在链接器属性中使用/ ASSEMBLYLINKRESOURCE选项似乎是最简单的解决方案.它使Visual Studio将本机dll视为程序集的一部分.此外,根据Microsoft提供的文档,允许将本机dll安装在全局程序集缓存中
要在Visual C++项目中设置此链接器选项:
您将需要Post Build事件将本机dll复制到输出文件夹.
从任何其他Visual Project引用托管程序集,强制将本机dll与/ bin文件夹中的托管程序集一起复制.
| 归档时间: |
|
| 查看次数: |
1892 次 |
| 最近记录: |