您的位置:首页 > 编程语言 > C语言/C++

程序员的自我修养: 程序运行的基石-C/C++运行库

2010-03-10 21:26 274 查看
一个C语言运行库大致包含了如下功能:

1. 启动与退出: 包括入口函数及入口函数所依赖的其它函数等

2. 标准函数: 由C语言标准规定的C语言标准库所拥有的函数实现.

3. I/O: IO功能的封装和实现

4. 堆:堆的封装和实现

5. 语言实现: 语言中一些特殊功能的实现.

6. 调试: 实现调试功能的代码.

在这些运行库的组成成分中, C语言标准占据了主要并且大有来头.

1. 变长参数

函数的实现如下:

#define _crt_va_start(ap,v)  ( ap = (va_list)_ADDRESSOF(v) + _INTSIZEOF(v) )
//va_start取第一个参数的地址, 并在栈上向上移动指针

#define _crt_va_arg(ap,t)    ( *(t *)((ap += _INTSIZEOF(t)) - _INTSIZEOF(t)) )
//va_arg主要是先移动指针,再取上一个值.
//注意: t是指要传入的类型,应为要确定移动的指针的远近.

#define _crt_va_end(ap)      ( ap = (va_list)0 )
//使ap指针为0

//主要是利用栈的原理.


#include <stdio.h>
#include <stdarg.h>
int sum(int a, ...)
{
int v = 0;
va_list ap;
va_start(ap, a);
while(a--)
v += va_arg(ap, int);
va_end(ap);
return v;
}

int main()
{
printf("%d", sum(9, 1,2,3,4,5,6,7,8,9));
return 0;
}


2. 非局部跳转

#include <setjmp.h>
jmp_buf b;

void f()
{
longjmp(b, 1);
}

int main()
{
if(setjmp(b))
printf("World!");
else
{
printf("Hello ");
f();
}
return 0;
}


结果: Hello World!

当调用longjmp时,运行到setjmp返回的位置,并把setjmp的返回设置为1

关于不同版本CRT的问题

1. 为什么用VC2008编译的程序无法在别人的机器上运行?

因为VC2008编译的程序使用了manifest机制, 这些程序必须依赖于相对应版本的运行库.

一个解决办法就是使用静态链接, 这样就不需要依赖于CRT的DLL.

另一办法是将相应版本的运行库与程序一起发布给最终用户.

2. 如果一个程序里面的不同obj文件或dll文件使用了不同的CRT, 会不会有问题?

如果只有obj没有dll, 这时是静态链接, 不同的obj在编译时用到了不同版本的静态CRT. 一般是不会出现问题的. 因为目标文件对静态库引用只是在目标文件的符号表中保留一个记号, 不进行链接, 没有静态库的版本信息.

但是如果含有不同版本的dll文件, 则有可能出现问题.
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: