网站首页 > 技术文章 正文
起因
文章在19年写,因为最近在学习.Net CoreCLR源码,觉得Mono的设计还是很先进的, .Net 5单文件发布,应该是吸收Mono的思想,所以才把这篇文章迁移过来,Mono这几年也是一直在改进.
Mono是支持将C#程序集嵌入到C语言生成的可执行程序中.这里借用mono官方文档的图片.具体参考mono文档:
//文档地址
https://www.mono-project.com/docs/advanced/embedding/
生成Mono Runtime
上图有Mono Runtime,具体是什么呢?
先用MingW编译mono.这里直接使用mono官网下载的,不是从github上下载的(最近使用github比较慢),两个还是有些区别的.最好是使用github 当下来.
下载mono-6.0.0.313.tar.xz,进行解压.最好在msys2中进行解压.在MingW中进行编译.这里采用64位的MingW,进入解压后的mono目录.
./autogen.sh --prefix=/e/opensource/mymono/ --host=x86_64-w64-mingw32 --disable-boehm
没有报错的话,就能看到下图:
执行make和make install 进行编译和安装.上次编译并没有安装--prefix指定的目录,执行一半.我们想要的是编译成功的.
make && make install
MingW默认执行是MingW64/bin目录下的可执行程序.到这里只是.Net Framework的类库没有编译完成,Mono的Runtime(运行时)在这已经编译成功了.
生成好的文件在mono/mini/.libs/下.
分别为libmonosgen-2.0.a(静态库)和libmonosgen-2.0.dll(动态库),这里主要使用的是静态库.
准备好,链接Mono Runtime环境
因为上次编译没有完成.还是需要下载一个mono Windows平台的安装,然后提取链接需要的头文件.
因为省事,直接把mono-2.0下mono目录,拷贝到MingW的include目录中.将静态库放到MingW/lib中.
链接代码
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
//mono所需头文件
#include <mono/jit/jit.h>
#include <mono/metadata/assembly.h>
int main(int argc, char* argv[])
{
//设置c#依赖库目录为lib 配置从etc目录读取
mono_set_dirs("lib", "etc");
//指定.Net 版本为4.0
MonoDomain* domain = domain = mono_jit_init_version("myapp", "v4.0.30319");
//这里固定加载c#程序名称为hello.exe
MonoAssembly* assembly = mono_domain_assembly_open(domain, "hello.exe");
if (!assembly)
{
printf("open assembly failed!\n");
exit(0);
}
//执行c#程序集
int retval = mono_jit_exec(domain, assembly, argc, argv);
//释放mono运行时资源
mono_jit_cleanup(domain);
return retval;
}
#编译pack 链接所需静态库
gcc -g -o pack.exe pack.c -lmonosgen-2.0 -lmswsock -lws2_32 -lpsapi -lole32 -lwinmm -loleaut32 -ladvapi32 -lversion -lbcrypt -lz
今年看Mono 把zlib移入到源码中,上边链接-lz,在后面的版本不需要了.
生成好的pack.exe.
生成的目标可执行程序,还是有些大的.使用strip清除调试符号.
#使用strip 去除程序不需要符号信息
strip pack.exe
去掉调试符号的程序大小,是下图pack.exe的大小,这个文件的大小,我们是可以接受的,如果还嫌文件大,可以用UPX进行压缩
因为还没有将c#程序嵌入c Native程序,这里需要mscorlib.dll文件.
在pack.exe目录,按lib/mono/4.5目录路径,创建目录,并将mscorlib.dll拷贝过来.
在.Net 5/6中是没有mscorlib.dll,改为
System.Private.CoreLib.dll, Mono中目前还需要
猜你喜欢
- 2025-05-10 热学和湿度超稳定的一维钙钛矿(钙钛矿eqe)
- 2025-05-10 C#上位机基于SMTP实现邮件报警通知
- 2025-05-10 Android平台上最好的几款免费的代码编辑器
- 2025-05-10 CPU缓存一致性:从理论到实战(cpu和缓存)
- 2025-05-10 头文件路径搜索顺序五花八门,有没有规律?
- 2025-05-10 .NET 7 AOT 的使用以及 .NET 与 Go 互相调用
- 2025-05-10 Linux系列:如何用 C#调用 C方法造成内存泄露
- 2025-05-10 测评丨RK3399+RK1808人工智能计算棒(主动模式和被动模式)
- 2025-05-10 C语言简介(c语言编程介绍)
- 2025-05-10 海康工业相机SDK开发介绍(海康 工业相机)
- 05-11官方资源!多所知名高校课程,这个平台免费开放→
- 05-11说好的免费课程学剪辑 怎么会“花”掉10万?
- 05-11免费公开!中小学国家课程教材电子版来了
- 05-11338所知名高校50万门课,全免费!赶紧收藏
- 05-11免费课程来了,快来解锁你的艺术“超能力”吧~
- 05-10热学和湿度超稳定的一维钙钛矿(钙钛矿eqe)
- 05-10C#上位机基于SMTP实现邮件报警通知
- 05-10Android平台上最好的几款免费的代码编辑器
- 最近发表
- 标签列表
-
- cmd/c (64)
- c++中::是什么意思 (83)
- 标签用于 (65)
- 主键只能有一个吗 (66)
- c#console.writeline不显示 (75)
- js判断是否空对象 (63)
- pythoncase语句 (81)
- es6includes (73)
- sqlset (64)
- windowsscripthost (67)
- apt-getinstall-y (86)
- node_modules怎么生成 (76)
- localstorage.removeitem (74)
- vector线程安全吗 (70)
- & (66)
- java (73)
- org.redisson (64)
- js数组插入 (83)
- gormwherein (64)
- linux删除一个文件夹 (65)
- mac安装java (72)
- outofmemoryerror是什么意思 (64)
- eacces (67)
- 查看mysql是否启动 (70)
- 无效的列索引 (74)