任何依赖于 C++/CLI 的 CPU 依赖于本机 C dll(任何用于 c++/cli 的 cpu)
这是我的问题。 我正在用 C# 封装 C dll。为此,我首先编写一个 C++/CLI 包装器。本机 C 库链接到 C++/CLI 包装器。 (C++/cli 项目中的链接器属性)。
现在的组织方式如下: - 本机 C .lib:x86 和 64 位。
- 1 个解决方案包含 2 个项目:
- 链接到本机 C .lib 的 C++/CLI 包装器项目
- 引用 C++/CLI 项目的 C# 项目
我的问题来自于我需要 C# 来定位“任何 CPU”这一事实。但此选项在 C++/CLI 中不可用,因为它直接编译为本机代码。
我解决这个问题的想法是: - 在 x86 中编译 C++/CLI 包装器,然后更改配置并编译为 64 位。当它编译时,我想告诉它根据平台采用哪个dll。即:如果在 64 位中编译,则链接 64 位本机 C dll,否则如果在 x86 中编译,则链接 x86 本机 C。 - 完成此操作后,我应该能够在我的 C# 平台中拥有任何 CPU 目标。在这里,我不会引用我的 C++/CLI 包装器项目,而是根据目标平台引用所需的 dll。
我的问题是:
- 如何告诉 C++/CLI 项目根据目标平台链接到哪个 .lib?
- 如何告诉 C# 项目根据目标平台引用哪个 C++/CLI dll?
让我补充一点,C# 项目是一个供 x86 或 x64 客户端使用的 CLASS LIBRARY。
我希望我的问题足够清楚。任何帮助将不胜感激!
更新基于:.NET 项目中的条件引用,可以摆脱警告吗?...
所以现在我已经使用条件引用 dll 编辑了我的 .csproj 文件,如下所示:
<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>
不幸的是,这不起作用,因为$(Platform) 设置为 AnyCPU...
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

发布评论
评论(2)
对我来说,解决方案如下:
构建 x64 位版本的 C++ 库以输出文件 xxx.x64.dll
构建 x86 位(Win32 平台)版本的 C++ 库以输出文件 xxx.x86.dll
将它们作为内容文件添加到我的包装器 C# 项目中。例如:
; <内容包含=“..\..\$(配置)\xxx.x86.dll”链接=“xxx.x86.dll”> <复制到输出目录>保留最新的 <内容包含=“..\..\$(配置)\xxx.x64.dll”链接=“xxx.x64.dll”> <复制到输出目录>保留最新的 在 C# 中,从 x86 和 x64 库版本导入函数。例如:
[DllImport("xxx.x86.dll", EntryPoint = "FunctionName", SetLastError = true, CharSet = CharSet.Unicode, ExactSpelling = true, CallingConvention = CallingConvention.Cdecl)] 公共静态 extern void FunctionNamex86(); [DllImport(“xxx.x64.dll”,EntryPoint =“FunctionName”,SetLastError = true,CharSet = CharSet.Unicode,ExactSpelling = true,CallingConvention = CallingConvention.Cdecl)] 公共静态 extern void FunctionNamex64();
在 C# 中实现根据当前平台调用正确重载的函数。例如:
public static void 函数名() { 如果(环境.Is64BitProcess) 函数名称x64(); 别的 函数名x86(); }
现在 C# 项目可以构建为“任何 CPU”并由其他多平台项目使用。
要将其作为 NuGet 包分发,我使用以下 NuSpec 配置:
<封装> <元数据> <内容文件>
> > <文件> <文件 src="Release/C#Wrapper.dll" target="lib" /> <文件 src="Release/xxx.x64.dll" target="内容" /> <文件 src="Release/xxx.x86.dll" target="内容" /> <文件 src="Release/xxx.x64.dll" target="contentFiles/any/any" /> <文件 src="Release/xxx.x86.dll" target="contentFiles/any/any" />
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
您所描述的内容被称为“并行程序集”(同一程序集的两个版本,一个是 32 位,另一个是 64 位)...我认为您会发现这些很有帮助:
编辑 - 根据评论:
在这里您可以找到适合您的场景的演练:http://www.thescarms.com/dotnet/Assembly.aspx archive.org/web/20180118101655/http://scottbilas.com/blog/automatically-choose-32-or-64-bit-mixed-mode-dlls/” rel="nofollow noreferrer">.NET DLL 包装引用本机 DLL 的 C++/CLI DLL
What you describe is known as "side-by-side assembly" (two versions of the same assembly, one 32 and the other 64 bit)... I think you will find these helpful:
EDIT - as per comment:
Here you can find a walkthrough for exactly your scenario: .NET DLL wrapping C++/CLI DLL referencing a native DLL