VC2015编写不需要运行库的资磁(支持)XP的程序
金坷居士2016/05/23软件综合 IP:澳大利亚
VC制作的软件,从VC2005之后的都需安装运行库才可以运行,从xp到win10一直都没改变,而且这货,上下版本还不能互相兼容orz这就是为啥在添加和删除程序里能看到各版本VC运行库的原因。
在某些情况下,比如绿色软件或者在pe下运行的软件,运行库可能带不全或者不好安装,于是制作一个不需要VC运行库的程序就是很有必要的了
首先创建一个VC2015的Win32 Project,选择默认选项创建一个窗体程序
打开菜单Project-> xxx Property(xxx是项目名)或者直接按Alt+F7,
选择Configuration为All Configuration, Platform为All Platform
将Basic Runtime Checks改为Default
将Security Check改为Disable Security Check(/GS-)
在stdafx.h的#progma once下面添加:
<code class="lang-cpp">#ifdef _DEBUG
#pragma comment (linker, "/nodefaultlib:msvcrtd.lib")
#else
#pragma comment (linker, "/nodefaultlib:msvcrt.lib")
#endif</code>

这时候编译一般会出现一堆堆的错误
首先解决LNK2001 unresolved external symbol wWinMainCRTStartup, wWinMainCRTStartup是VC的CRT定义的Win32程序入口点,MFC程序为WinMainCRTStartup,控制台和DLL为mainCRTStartup和_DllMainCRTStartup。
没有了运行库就没有了入口点orz没有入口点就创建一个咯,wWinMainCRTStartup不接收任何参数,我写的入口如下,可以放在stdafx.cpp里:
<code class="lang-cpp">int __cdecl wWinMainCRTStartup() {
    STARTUPINFO info;
    info.cb = sizeof(STARTUPINFO);
    GetStartupInfo(&info);
  
    int ret = wWinMain(GetModuleHandle(NULL),
        0,
        GetCommandLine(),
        info.dwFlags & STARTF_USESHOWWINDOW ? info.wShowWindow : SW_SHOWDEFAULT);
    ExitProcess(ret);
    return ret;
}</code>

之后应该就可以顺利编译工程了,这样制作出来的程序和静态链接的程序比起来,体积极小
本方法并不是完美的,有这些缺点:
C++的异常不能用了, new delete也不能用了,也就是说这时候C++基本完全废了
C和C++的标准库大部分也都不能用了,不过这个有解决方法,我自己想出来的,可能不是很完美,就是手动实现某些stdlib里的函数,给了些常用的实现,都是互联网上搜索的:
<code class="lang-cpp">void* __cdecl malloc(ULONG_PTR uSize) {
    return (void *)HeapAlloc(GetProcessHeap(), 0, uSize);
}
  
void __cdecl free(LPVOID pMemBlock) {
    HeapFree(GetProcessHeap(), 0, (LPVOID)pMemBlock);
}


#pragma function(memcpy)

void* memcpy(void * dst, const void * src, size_t count)
{
    void * ret = dst;
  
#if defined (_M_IA64)
    {
        extern void RtlMoveMemory(void *, const void *, size_t count);
  
        RtlMoveMemory(dst, src, count);
    }
#else /* defined (_M_IA64) */
    /*
    * copy from lower addresses to higher addresses
    */
    while (count--) {
        *(char *)dst = *(char *)src;
        dst = (char *)dst + 1;
        src = (char *)src + 1;
    }
#endif /* defined (_M_IA64) */
  
    return(ret);
}
  
#pragma function(memset)
void* __cdecl memset(void* src, int c, size_t count) {
    char *tmpsrc = (char*)src;
    while (count--)
        *tmpsrc++ = (char)c;
    return src;
}</code>

有的时候编译会看到俩错误,找不到__imp__invalid_parameter_noinfo和__imp__errno,并不晓得这俩是啥,于是空函数代替之:
<code class="lang-cpp">extern "C" void __cdecl __imp__invalid_parameter_noinfo() {
  
}
  
extern "C" void __cdecl __imp__errno() {
  
}</code>


还有个说不清的问题,就是调用COM组件的时候有点奇怪。。
还有,MFC不适用!也就是说,复杂的软件就不要用这种方法咯
参考
XXXXXXXXXXXXXXXXXXXXXXXX/t/80005
XXXXXXXXXXXXXXXXXXXXXXXX/questions/2938966/how-to-use-vc-intrinsic-functions-w-o-run-time-library

[修改于 8年6个月前 - 2016/06/17 19:11:11]

来自:计算机科学 / 软件综合
6
已屏蔽 原因:{{ notice.reason }}已屏蔽
{{notice.noticeContent}}
~~空空如也
acmilan
8年6个月前 修改于 8年6个月前 IP:四川
821611

感觉这样还不如用汇编。。。

便携性的话,静态编译就够用了。兼容性的话,去掉运行库提升有限,直接降编译器版本或者用MinGW效果更好。

引用
评论
加载评论中,请稍候...
200字以内,仅用于支线交流,主线讨论请采用回复功能。
折叠评论
drzzm32
8年6个月前 IP:陕西
821749

gcc+自备源码,到目标机运行的时候再编译(只是gcc还要安装不易携带) 或者。。。使用网页应用,但是不适合复杂计算等

引用
评论
加载评论中,请稍候...
200字以内,仅用于支线交流,主线讨论请采用回复功能。
折叠评论
acmilan
8年2个月前 IP:四川
826949
引用 drzzm32:
gcc+自备源码,到目标机运行的时候再编译(只是gcc还要安装不易携带)
或者。。。使用网页应用,但是不适合复杂计算等
直接codeblocks绿色版。。。
引用
评论
加载评论中,请稍候...
200字以内,仅用于支线交流,主线讨论请采用回复功能。
折叠评论
amo
8年2个月前 IP:广东
826970
VC6.0一直用的很high的路过……

我用的都是比较底层的东西,没有花里胡哨的,所以用一个老的编译器,直接就不用考虑不同的客户会用什么版本的windows了
引用
评论
加载评论中,请稍候...
200字以内,仅用于支线交流,主线讨论请采用回复功能。
折叠评论
acmilan
8年2个月前 修改于 8年2个月前 IP:四川
826972
引用 amo:
VC6.0一直用的很high的路过……

我用的都是比较底层的东西,没有花里胡哨的,所以用一个老的编译器,直接就不用考虑不同的客户会用什么版本的windows了
个人用vc++2005比较多→_→其实主要是因为vc6在win7中用着不爽→_→不过现在顶多用到vs2010了吧,谁会用xp sp2之前的系统呢
引用
评论
加载评论中,请稍候...
200字以内,仅用于支线交流,主线讨论请采用回复功能。
折叠评论
金坷居士作者
7年0个月前 IP:北京
841130
新的发现,如果按照上面的还是出错的话

1. Configuration Properties -> C/C++ -> Optimization -> Whole Program Optimization = false
2. Configuration Properties -> C/C++ -> Optimization -> Enable Intrinsic Functions = false
3. #include <Windows.h> 要写成
#define WIN32_LEAN_AND_MEAN
#include <Windows.h>
不然会找不到malloc
引用
评论
加载评论中,请稍候...
200字以内,仅用于支线交流,主线讨论请采用回复功能。
折叠评论

想参与大家的讨论?现在就 登录 或者 注册

所属专业
所属分类
上级专业
同级专业
金坷居士
学者 机友 笔友
文章
170
回复
1711
学术分
11
2011/09/23注册,3个月5天前活动

怪哉!灵异的三极管电流流向! 这素一个在仿真的RCC电路,示波器上绿色的是集电极电流红色的是发射极电流。窝萌都知道发射姬电流素集电极电流和基极电流之和,所以讲道理发射极电流一定比集电极略大。可仿真结果刷了三观,Q1集电极电流一部分流经基极,然后流经Q2的C->E。

主体类型:个人
所属领域:无
认证方式:手机号
IP归属地:未同步
文件下载
加载中...
{{errorInfo}}
{{downloadWarning}}
你在 {{downloadTime}} 下载过当前文件。
文件名称:{{resource.defaultFile.name}}
下载次数:{{resource.hits}}
上传用户:{{uploader.username}}
所需积分:{{costScores}},{{holdScores}}下载当前附件免费{{description}}
积分不足,去充值
文件已丢失

当前账号的附件下载数量限制如下:
时段 个数
{{f.startingTime}}点 - {{f.endTime}}点 {{f.fileCount}}
视频暂不能访问,请登录试试
仅供内部学术交流或培训使用,请先保存到本地。本内容不代表科创观点,未经原作者同意,请勿转载。
音频暂不能访问,请登录试试
支持的图片格式:jpg, jpeg, png
插入公式
评论控制
加载中...
文号:{{pid}}
投诉或举报
加载中...
{{tip}}
请选择违规类型:
{{reason.type}}

空空如也

加载中...
详情
详情
推送到专栏从专栏移除
设为匿名取消匿名
查看作者
回复
只看作者
加入收藏取消收藏
收藏
取消收藏
折叠回复
置顶取消置顶
评学术分
鼓励
设为精选取消精选
管理提醒
编辑
通过审核
评论控制
退修或删除
历史版本
违规记录
投诉或举报
加入黑名单移除黑名单
查看IP
{{format('YYYY/MM/DD HH:mm:ss', toc)}}