- android - RelativeLayout 背景可绘制重叠内容
- android - 如何链接 cpufeatures lib 以获取 native android 库?
- java - OnItemClickListener 不起作用,但 OnLongItemClickListener 在自定义 ListView 中起作用
- java - Android 文件转字符串
我的 VS2008 解决方案包含一个生成 C# 可执行文件的项目,该项目引用一个生成包含 C++/CLI 和非托管 C++ 的 dll 的项目。
我想将它们合并到一个可执行文件中,因为 C++ dll 包含我想嵌入到主可执行文件中的安全代码。
我不能使用 ILMerge,因为 dll 包含托管和非托管代码。建议的解决方案似乎是使用 link.exe 将 C# 程序集与 C++ 目标文件链接起来。这就是我想要做的。
我手动编辑了 c# 可执行文件的项目文件以生成网络模块。我向可执行项目添加了构建后步骤以运行 link.exe 将 c# netmodule 和编译的 C++ 目标文件链接在一起,然后运行 mt.exe 合并两个项目创建的程序集 list 。这运行成功,但 exe 仍然包含对 C++ 项目的正常构建过程生成的 dll 中定义的 C++ 类型的引用和使用。
然后我在 C++ dll 的项目设置中指定了/NOASSEMBLY,因此它也生成了一个网络模块。在 C# 项目中,我删除了对 C++ 项目的引用,但在解决方案中添加了项目依赖项。我手动编辑了 C# 项目文件以包含类似于:
<ItemGroup>
<AddModules Include="..\Debug\librarycode.netmodule" />
</ItemGroup>
即引用现在由 C++ 项目生成的 C++ 网络模块。
但是,现在我的构建后事件中的链接器步骤失败了:
error LNK2027: unresolved module reference 'librarycode.netmodule'
fatal error LNK1311: 1 unresolved module references:
这是完全可以理解的,因为我没有在 librarycode netmodule 中链接;我正在链接用于生成网络模块的 C++ 目标文件。
简而言之,如何将 C# 可执行文件和 C++ 目标文件合并到一个程序集中?我错过了什么?
到目前为止,我的引用来源(来自 MSDN 上的 link.exe 命令链接引用等)是以下两篇文章:
非常感谢您。
我完全遵循了 Steve Teixeira 博客中的示例,并验证了它的有效性。使用反射器,我可以看到生成的可执行文件包含两个网络模块。 c# 网络模块包含对另一个网络模块的引用,但没有名称?!如果将程序集移动到新目录,第二个网络模块将变为未引用(很明显),但可执行文件仍会运行,因为具有正确定义的类型存在于 c# 网络模块中。
请注意,原始的 c# netmodule 确实包含对 c++ netmodule 的命名引用,因此它必须是删除名称的链接器步骤。
尝试在我的示例项目中遵循此示例,我在构建后链接器步骤中添加了一个/ASSEMBLYMODULE 参数。链接器现在失败并显示
LNK2022: metadata operation failed (80040427) : Public type 'MixedLanguageLibrary.Class1' is defined in multiple places in this assembly: 'MixedLanguageDemo.exe' and 'mixedlanguagelibrary.netmodule'
LINK : fatal error LNK1255: link failed because of metadata errors
我猜是链接器魔术删除了我丢失的模块引用名称。
欢迎任何想法。
我已将我的项目缩减到尽可能简单的程度,并且正在尝试从命令行进行编译。以下批处理文件成功构建了 Steve Teixeira 博客中的示例:
setlocal
call "C:\Program Files\Microsoft Visual Studio 9.0\VC\vcvarsall.bat"
if errorlevel 1 goto End
cl /c /MD nativecode.cpp
if errorlevel 1 goto End
cl /clr /LN /MD clrcode.cpp nativecode.obj
if errorlevel 1 goto End
csc /target:module /addmodule:clrcode.netmodule Program.cs
if errorlevel 1 goto End
link /LTCG /CLRIMAGETYPE:IJW /ENTRY:ConsoleApplication1.Program.Main /SUBSYSTEM:CONSOLE /ASSEMBLYMODULE:clrcode.netmodule /OUT:MixedApp.exe clrcode.obj nativecode.obj program.netmodule
:End
以下批处理文件无法构建我的示例代码,链接器错误为 LNK2022:
setlocal
call "C:\Program Files\Microsoft Visual Studio 9.0\VC\vcvarsall.bat"
if errorlevel 1 goto End
cl /c /MD messageprovider.cpp
if errorlevel 1 goto End
cl /clr /LN /MD managedmessageprovider.cpp messageprovider.obj
if errorlevel 1 goto End
csc /target:module /addmodule:managedmessageprovider.netmodule Program.cs Form1.cs Form1.Designer.cs
if errorlevel 1 goto End
link /LTCG /CLRIMAGETYPE:IJW /ENTRY:MixedLanguageDemo.Program.Main /SUBSYSTEM:WINDOWS /ASSEMBLYMODULE:managedmessageprovider.netmodule /OUT:MixedLanguageDemo.exe managedmessageprovider.obj messageprovider.obj program.netmodule
:End
是时候发现差异了:-(
最佳答案
以下是一个 Nant 构建脚本,它完全可以满足您(和我)的需求(如果我正确理解了您的需求,那就是 xD)。
其中一些缺失(比如一些变量,并不是真正需要的),但事实证明它实际上很容易实现。
这显示了您需要能够合并混合程序集和托管程序集的 cl/csc 和链接器标志。此外,作为额外的“奖励”,所有内部类/方法/字段等在整个新程序集中都是可见的,这意味着它们跨越了项目的边界。
<delete file="${tmp.cpp}" />
<foreach item="File" property="filename">
<in>
<items basedir="${basedir}/SpotiFire.LibSpotify">
<include name="**.h" />
</items>
</in>
<do>
<echo message="#include "${filename}" " append="true" file="${tmp.cpp}" />
</do>
</foreach>
<cl outputdir="${build.obj}" options="/clr /LN">
<sources basedir="${basedir}/SpotiFire.LibSpotify">
<include name="*.cpp" />
<include name="${tmp.cpp}" asis="true" />
<exclude name="AssemblyInfo.cpp" />
</sources>
</cl>
<csc target="module" output="${build.obj}/SpotiFire.netmodule">
<modules basedir="${build.obj}">
<include name="tmp.obj" />
</modules>
<references refid="all_refs" />
<sources basedir="${basedir}/SpotiFire.SpotifyLib">
<include name="**.cs" />
</sources>
</csc>
<link output="${build.dir}/${name}.dll" options="/LTCG /FIXED /CLRIMAGETYPE:IJW /NOENTRY /DLL">
<sources basedir="${build.obj}">
<include name="*.obj" />
<include name="*.netmodule" />
<include name="${basedir}/libspotify.lib" asis="true" />
</sources>
<arg value="/DEBUG" if="${build.debug == 'true'}" />
</link>
关于c# - 如何将 C# 和 C++ 程序集链接到单个可执行文件中?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/2609056/
C#内部访问修饰符的定义是内部:只能在包含程序集或友元程序集内访问。所以我的问题是什么是 C# 程序集?在包含程序集或 friend 程序集之内是什么意思?它是否意味着在同一个命名空间或项目中? 最佳
任何人都可以回答以下问题。我正在使用 c# 语言。 我可以将程序集调用为 .ddl 或 .exe 文件吗? 我可以将 Assembly Manifest 称为程序集吗? 程序集、元数据和程序集 lis
我正在从 Python 运行一个 .NET COM 程序集,只有当我将程序集 dll 和依赖项复制到我的 Python 根路径 c:\Python27 时才能使它正常工作。 这是不整洁的,所以我想将
作为世界上任何一名程序员,他/她一生中至少有一次,我正在尝试创建我的“革命性”,新的且唯一的操作系统。 :D 好吧,我正在使用虚拟模拟器(Oracle VM Virtual Box),为此我创建了一个
我创建了以下程序来读取 5 个数字,然后 dumpreg查看输入的数字... INCLUDE Irvine32.inc .data count = 5 scor
如何在保护模式下执行 IN 和 OUT 等受限指令? 我发现它需要足够高的特权级别(CPL)才能执行 IO 指令。我怎样才能在内核模式下运行,拥有 IO 权限或任何其他可能对我有帮助的东西? - 我希
目录 C# 程序集、模块和类型概念及关系 概述 程序集 模块 类型 程序集、模块和类型的关系 总结 引用
构建 maven assembly ,我留下了这样的东西: ${project.basedir} / LICENS
我的应用程序由几个核心程序集和几个扩展/插件程序集组成。为了让 MEF 知道插件必须提供的所有部件,即使我永远不会使用它们的任何部件,我也必须加载这些程序集。这使得应用程序需要更多时间来启动(如果我要
我对我们的构建基础结构有一个非常具体的要求,即将另一个 JAR 依赖项的一些内容复制到我的 Web 应用程序的特定子文件夹中。我们正在使用 maven-assembly-plugin,一个自然的方法是
为什么下面的指令会设置符号标志? mov al,0FEh sub al,2 据我了解,AL寄存器可以保存2^8 - 1或255。0FEh = 254(十进制)。减去 2 叶 252。这似乎是正数。 (
我以前使用过 NUnit,但已经有一段时间了,而且从来没有在这台机器上使用过。我在 Program Files 下解压了 2.4.8 版本,并且在尝试加载测试时不断收到此错误。 Could not l
我说的是一个使用 C# 进行游戏编程的小型游戏引擎。所以,我有一个嵌入单声道运行时的 C++ 应用程序(我称之为“启动器”)。我有一个用 C# 编写的程序集,它是我的游戏引擎类库。启动器按照 Embe
我对汇编相当陌生,并尝试从标准输入读取值(从 C 调用 scanf 函数)并将其打印回标准输出(使用 printf)。 .text readstr: .asciz "%d" #strin
谢谢帮助,我的问题是关于从下面的代码中收到的 ax 值? mov al,22h mov cl,0fdh imul cl 真机结果:ff9a 我的预期:00:9a(通过二进制相乘) 第一个数字是 22h
我正在开发一个汇编程序,该程序将整个文本文件读入缓冲区,然后将其显示在控制台中。它立即显示 24 行(每行的最大长度为 80,因为我使用 80 宽 * 25 高的 dossbox )然后等待用户输入,
我正在使用一个简单的程序集片段,使用 BIOS 作为引导加载程序的一部分将字符打印到屏幕上。这是引导加载程序代码。 [org 0x7c00] [bits 16] %include "a20_check
我只是想知道这段代码是什么意思: XOR EAX,EBX XOR EBX,EAX XOR EAX,EBX 最佳答案 那是 xor swapping . 在寄存器上执行它不会遇到常见的难看的失败案例。
我在新电脑上的 XNA 项目开始出现奇怪的错误。我有两个关于解决方案的项目和一个由它们使用的库。其中一个项目,一个 XNA 游戏项目,运行完美。另一个项目是 WindowsForm 和 XNA 的混合
是的,我正在努力实现类似的目标 __asm__(jmp label;); 其中 label 应替换为内存中保存的字符串值(结构体的字段)。 有没有办法做到这一点(或类似的方法可以让我跳转到运行时确定的
我是一名优秀的程序员,十分优秀!