最近在研究如何使一个VC编译的程序脱离VC运行库,也就是msvcrXX.dll。查了许多资料,最后确定了两篇可参考文章,不过都是以VC2010为开发环境的,而我用的是VC2012,和他们的有所不同。首先,要把msvcrXX.dll脱离出来,第一步是取消链接库,代码是:
#pragma comment (linker, "/nodefaultlib:msvcrt.lib") /*If _DEBUG, it should be msvcrtd.lib*/

这样就把msvcrXX.dll去掉了,但是接下来的就问题无限了,比如,mainCRTStartup 函数没了。(这是Console程序,对于Windows程序应该是WinMainCRTStartup)。写过Windows SDK程序的人都知道,对于UNICODE和非UNICODE程序,入口函数是不一样的,为了统一,我们先指定下入口函数。

#pragma comment (linker, "/entry:mainCRTStartup")
此外,没有 CRT 的时候,没法进行基本运行时检查,所以打开“项目属性-C/C++-代码生成”,把“基本运行时检查”改为“默认值”。(Release配置不用改,只改Debug)。下面是入口函数实现:
#include <Windows.h>
int __cdecl mainCRTStartup() {WriteFile(GetStdHandle(STD_OUTPUT_HANDLE), "Hello World!\r\n", 14, NULL, NULL);return 0;
}
编译运行,Sorry,出错了。错误提示:
1>main.obj : error LNK2001: 无法解析的外部符号 @__security_check_cookie@4
这个错误提示比较简单解决,只需引入 bufferoverflowU.lib 即可。
#pragma comment (lib,"bufferoverflowU.lib")

这下再编译运行,OK了,此时程序只有3.5KB。但是,试试使用malloc?printf?或者是使用C++类?不好意思,这是VC运行库的内容。那么,似乎这么做毫无意义了?那也未必,如果你只是要 C 编程,那么可以把部分函数重写。比如:

void *mem_alloc(ULONG_PTR uSize) {return (void *)HeapAlloc (GetProcessHeap(), 0,uSize);
}void mem_free (LPVOID pMemBlock) {HeapFree (GetProcessHeap(), 0, (LPVOID)pMemBlock);
}void *operator new (size_t uSize) {return (void *)HeapAlloc (GetProcessHeap(), 0,uSize);
}void operator delete (void *pMemBlock) {HeapFree (GetProcessHeap(), 0, (LPVOID)pMemBlock);
}void *operator new[] (size_t uSize) {return (void *)HeapAlloc (GetProcessHeap(), 0,uSize);
}void operator delete[] (void *pMemBlock) {HeapFree (GetProcessHeap(), 0, (LPVOID)pMemBlock);
}DWORD echo(char *pszOutput) { /* Output a string */DWORD dwLen;dwLen = lstrlenA(pszOutput);WriteFile(GetStdHandle(STD_OUTPUT_HANDLE), pszOutput, dwLen, &dwLen, NULL);return dwLen;
}

此时测试结果是,C++异常无效(需要在工程设置里把C++异常关掉,否则会提示找不到__CxxFrameHandler3),也就是说,这时 C++ 几乎废了。

是否觉得这么做太烦了?其实,msvcrXX.dll是各个版本VC的运行库文件,VC2005开始都要独立安装,但是对于VC6,却几乎不存在这个问题。因为几乎Windows 2000开始的Windows系统都带有VC6的运行库,那么,用它取代掉就可以了!这个比较简单,在VC6安装包里,“VC\Lib\” 目录下,找到MSVCRT.LIB 和 MSVCRTD.LIB。前者是 Release 版本,后者是 Debug 版本,复制到工程目录下,分别命名为 msvcrt98.lib 和 msvcrt98d.lib,然后在代码里写:
#pragma comment (linker, "/nodefaultlib:msvcrt.lib") /* msvcrtd.lib If _DEBUG */
#pragma comment (lib, "msvcrt98.lib") /* msvcrt98d.lib If _DEBUG */
这里,引入了VC6的运行库,那么mainCRTStartup也已经写好了,所以入口函数写 main 即可。而且由于VC6的静态链接库太旧,没有“SAFESEH安全异常处理程序”,因此要把“项目属性-链接器-高级-映像具有安全异常处理程序”设置为“否 (/SAFESEH:NO)”。
到此,替代完成。malloc,printf 等 C 标准函数都可以用了。new,delete 等 C++ 运算符也可以用了,但是 C++ 异常依旧无效。
下面是一份完整代码:
#ifdef _DEBUG#pragma comment (linker, "/nodefaultlib:msvcrtd.lib")#pragma comment (lib, "msvcrt98d.lib")
#else#pragma comment (linker, "/nodefaultlib:msvcrt.lib")#pragma comment (lib, "msvcrt98.lib")
#endif#pragma comment (lib,"bufferoverflowU.lib")#include <windows.h>
#include <stdio.h>
#include <tchar.h>class A {
public:A(char *pszStr) {echo ("New A: ");echo (pszStr);echo ("\r\n");}~A() {echo ("Delete A\r\n");}void print() {echo ("A::print()\r\n");}
};int main() {A a("Static"), *pa;DWORD c;char *buf;buf = (char*)malloc(123);strcpy(buf, "Hello World\r\n");printf(buf);a.print();c = strlen("233213");pa = new A("Dynamic");pa->print();delete pa;free(buf);return 0;
}

用 VC2012 产生脱离VC运行库的 C/C++ 程序相关推荐

  1. c语言关于office运行库,VC++运行库32/64位合集下载|微软常用运行库合集(2015- 2021版)...

    Microsoft Visual C++简称Visual C++,是一款免费C++开发工具,具有集成开发环境,可提供编辑C语言,C++以及C++/CLI等编程语言.集成了便利的除错工具,特别是集成了微 ...

  2. Windows 典藏篇-vc++运行库安装,Microsoft Visual C++ Build Tools官方工具

    以前: 想安装最全最完整最新的 vc++ 运行库,莫非用 vs2017 安装了,这是 Microsoft 官方出品的,但是安装要安装整个 vs,非常的麻烦. 如今: 终于,终于,被我找到了这款工具! ...

  3. VC运行库安装错误0x80240017解决过程

    最近在一台全新的Windows 2012 Server x64上安装部署程序,程序无法正常启动,使用depend工具查看,一些底层的库找不到,比如msvcr140.vcruntime100等,这些库都 ...

  4. Win10 VC++运行库集合|VC++ 2005 2008 2010 2012 2015

    在Win10系统中很多朋友在运行一些软件时会遇到缺少.DLL的情况,主要是没有安装VC++运行库下面小编收集了Win10 VC++运行库集合,大家安装上去就可以了~ 微软常用软件运行库合集(vc201 ...

  5. win10自带vc运行库吗?

    运行库是系统中非常重要的组件,像一些绿化版的软件如果电脑没有运行库就无法运行,但是也不一定就要安装VC++运行库一般而言,将相关的.dll文件复制出来,放在相关程序所在目录中就可以了.比如小编从网上下 ...

  6. phpstudy安装php8.0和php8.1的方法(内含VC运行库)

    phpstudy8.1安装php8.0.14nts和php8.1.1nts的方法 phpstudy 8.1是个很好用的PHP集成环境软件,可惜官方一年多没更新了,官方只支持到PHP7.4,因为近期项目 ...

  7. vscode编译Window c++程序缺少vc运行库解决方法

    vscode编译的window程序默认拷贝到非开发者电脑会缺少vc运行库需要配置为Mtd模式这样其它电脑才能正常 vscode+cmakelist模式编译时只需要在cmakelist.txt文件中加入 ...

  8. 关于VC++运行库报错

    Microsoft Visual C++(简称Visual C++.MSVC.VC++或VC)是微软公司的C++开发工具,具有一体化开发环境,可提供编辑 C语言,C++以及C++/CLI等程式语言. ...

  9. VC编译DLL时,如何不依赖VC运行库

    用VC编译的DLL如果依赖VC运行库,分发时如果目标系统不带对应版本的VC支行库,将导致DLl调用失败,在编译时应设置不依赖VC运行库: 在C/C++/Code Generation的Runtime ...

  10. 双心一键获取winsxs的写入权限,解决VC运行库安装error1935错误

    @Echo off title 双心一键获取winsxs的写入权限,解决VC运行库安装error1935等错误 set path=%path%;%~dp0 setlocal EnableDelayed ...

最新文章

  1. python sanic 向别的服务器发送post请求_Sanic框架请求与响应实例分析
  2. node --- 模拟事件的异步
  3. NET问答:null != variable 和 variable != null 到底有什么区别?
  4. linux内核不识别分区,ubuntu14.04无法识别树莓派SD卡问题
  5. 测试手机功耗软件,借助软件测试手机基本峰值功耗
  6. 基于beautifulSoup进行电影网站排名的获取与格式化输出
  7. linux默认超级用户密码,新手:ubuntu超级管理员的密码设置
  8. Win10系统中耳机插入前后面板均没有声音
  9. 修改用友服务器ip地址,修改用友服务器ip地址
  10. Android MVP伴侣,Nucleus框架使用简介
  11. EasyPoi word导出教程
  12. 2021-09-29 计算BMI值(国际上常用的衡量人体胖瘦程度的一个标准)(要保留多少位有效数字可以用python内置的 round 函数)
  13. mysql 漏洞 wa_[漏洞案例]thinkcmf 2.x从sql注入到getshell实战
  14. 双目立体视觉简单介绍
  15. cod12正版链接在线服务器6,cod6盗版服务器管理命令(Cod6 pirated server management commands).doc...
  16. BL5372 RTC linux驱动
  17. linux中grep命令详解及使用示例
  18. java生成word文档_Java多种方式动态生成doc文档
  19. 推荐一款Mac的SVG浏览工具:Gapplin
  20. flash透明\flash置底无效\flash遮挡div的解决方法 兼容Firefox ,IE,chrome浏览器

热门文章

  1. vim 的配置详解/键盘映射配置详解
  2. 7.3 超标量流水线
  3. Core Location 电子围栏:入门
  4. java 身份证地址提取籍贯_输入身份证号获取籍贯、出生日期、性别
  5. SD-Host 控制器设计
  6. Python工具箱系列(十一)
  7. 工业产品生产许可证审查费用已取消
  8. 韩顺平 php大牛班课程,2016泰牛程序员韩顺平PHP大牛班HTML课程完整笔记资料.doc...
  9. CAD图纸无法编辑修改怎么回事?
  10. Centos7之卸载oracle11G