任何依赖于c++/ CLI的CPU依赖于本机C dll(任何用于c++/ CLI的CPU)
本文关键字:任何 CLI CPU 依赖于 c++ 用于 本机 dll | 更新日期: 2023-09-27 18:10:53
我的问题是。我在c#包装一个C dll。为此,我首先编写一个c++/CLI包装器。本机C库链接到c++/CLI包装器。(c++/cli项目中的链接器属性).
现在是这样组织的:-本机C .lib: x86和64位。
- 1个方案包含2个项目:
- c++/CLI包装器项目,本机C .lib
- c#项目引用c++/CLI项目
我的问题来自于我需要c#来瞄准"任何CPU"这一事实。但是这个选项在c++/CLI中不可用,因为它直接编译为本机代码。
我解决这个问题的想法是:—在x86环境下编译c++/CLI wrapper,然后修改配置,编译为64位。当它编译的时候,我想根据平台告诉它使用哪个dll。即:如果在64位编译,链接64位原生C的dll,否则如果是x86,链接x86原生C。-完成后,我应该能够在我的c#平台上有任何CPU目标。这里,我将再次引用基于目标平台的所需dll,而不是引用我的c++/CLI包装器项目。
我的问题是:
- 我如何告诉c++/CLI项目哪个。lib链接到基于目标平台?
- 我如何告诉c#项目哪个c++/CLI dll引用基于目标平台?
让我补充一下, c#投射了一个类库供x86或x64客户端使用。
我希望我的问题足够清楚。如有任何帮助,不胜感激!UPDATE基于:.NET项目中的条件引用,可能摆脱警告…
所以现在我已经编辑了我的.csproj文件,使用一个条件来引用dll,如下所示:
<ItemGroup>
<Reference Include="AlibCppWrapper, Version=1.0.4303.21410, Culture=neutral, PublicKeyToken=c0c17a53adc44091, processorArchitecture=AMD64"
Condition="$(Platform) == 'x64'">
<SpecificVersion>False</SpecificVersion>
<HintPath>..'x64'Debug'AlibCppWrapper.dll</HintPath>
</Reference>
<Reference Include="AlibCppWrapper, Version=1.0.4303.21410, Culture=neutral, PublicKeyToken=c0c17a53adc44091, processorArchitecture=x86"
Condition="$(Platform) == 'x86'">
<SpecificVersion>False</SpecificVersion>
<HintPath>..'Debug'AlibCppWrapper.dll</HintPath>
</Reference>
</ItemGroup>
不幸的是,这不起作用,因为$(平台)被设置为AnyCPU…
你所描述的就是所谓的"并排组装"。(同一个程序集的两个版本,一个32位,另一个64位)…我想你会发现这些很有帮助:
- 使用并行程序集加载x64或x32版本的DLL
- http://blogs.msdn.com/b/gauravseth/archive/2006/03/07/545104.aspx
- http://www.thescarms.com/dotnet/Assembly.aspx
编辑-按注释:
在这里你可以找到一个完全适合你的场景的演练:.NET DLL包装c++/CLI DLL引用本地DLL
我的解决方案如下:
-
构建x64位版本的c++库以输出文件xxx.x64.dll
-
构建x86位(Win32平台)版本的c++库以输出文件xxx.x86.dll
-
将它们作为内容文件添加到我的包装c#项目中。例:
<ItemGroup> <Content Include="..'..'$(Configuration)'xxx.x86.dll" Link="xxx.x86.dll"> <CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory> </Content> <Content Include="..'..'$(Configuration)'xxx.x64.dll" Link="xxx.x64.dll"> <CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory> </Content> </ItemGroup>
-
在c#中从x86和x64库版本导入函数。例:
[DllImport("xxx.x86.dll", EntryPoint = "FunctionName", SetLastError = true, CharSet = CharSet.Unicode, ExactSpelling = true, CallingConvention = CallingConvention.Cdecl)] public static extern void FunctionNamex86(); [DllImport("xxx.x64.dll", EntryPoint = "FunctionName", SetLastError = true, CharSet = CharSet.Unicode, ExactSpelling = true, CallingConvention = CallingConvention.Cdecl)] public static extern void FunctionNamex64();
-
在c#中实现基于当前平台正确调用重载的函数。例:
public static void FunctionName() { if (Environment.Is64BitProcess) FunctionNamex64(); else FunctionNamex86(); }
-
现在c#项目可以构建为"任意cpu"并被其他多平台项目使用。
-
要将其作为NuGet包分发,我使用以下NuSpec配置:
<?xml version="1.0"?> <package> <metadata> <contentFiles> <files include="any/any/xxx.x64.dll" buildAction="None" copyToOutput="true" /> <files include="any/any/xxx.x86.dll" buildAction="None" copyToOutput="true" /> </contentFiles> </metadata> <files> <file src="Release/C#Wrapper.dll" target="lib" /> <file src="Release/xxx.x64.dll" target="content" /> <file src="Release/xxx.x86.dll" target="content" /> <file src="Release/xxx.x64.dll" target="contentFiles/any/any" /> <file src="Release/xxx.x86.dll" target="contentFiles/any/any" /> </files> </package>