C
C运行库(glibc, GNU C Library)
参考C运行库实现https://ftp.gnu.org/gnu/glibc/glibc-2.0.6.tar.gz。
Windows下VC C运行库
msvcrt.dll
msvcrt20.dll
msvcrt40.dll
MSVCRTD.DLL
以上不同dll应用于不同的vc版本,MSVCRTD.DLL用于debug。
msvcr100.dll
msvcr100_clr0400.dll
msvcr100d.dll
msvcr110.dll
msvcr71.dll
以上不同dll应用于不同的vc版本,msvcr100d.dll用于debug。
静态链接库
LIBC.LIB
LIBCD.LIB
LIBCMT.LIB
LIBCMTD.LIB
C++运行库
LIBCP.LIB
LIBCPD.LIB
LIBCPMT.LIB
LIBCPMTD.LIB
LIBCPD.LIB用于debug。
LIBCPMT.LIB,LIBCPMTD.LIB为多线程实现,LIBCPMTD.LIB用于debug。
C/C++ entry
写道
mainCRTStartup(void)
wmainCRTStartup(void)
WinMainCRTStartup(void)
wWinMainCRTStartup(void)
Purpose:
These routines do the C runtime initialization, call the appropriate
user entry function, and handle termination cleanup. For a managed
app, they then return the exit code back to the calling routine, which
is the managed startup code. For an unmanaged app, they call exit and
never return.
Entry:
Function: User entry called:
mainCRTStartup main
wmainCRTStartup wmain
WinMainCRTStartup WinMain
wWinMainCRTStartup wWinMain
malloc
#define mALLOc malloc
#if __STD_C
Void_t* mALLOc(size_t bytes)
#else
Void_t* mALLOc(bytes) size_t bytes;
#endif
{
arena *ar_ptr;
INTERNAL_SIZE_T nb; /* padded request size */
mchunkptr victim;
#if defined(_LIBC) || defined(MALLOC_HOOKS)
if (__malloc_hook != NULL) {
Void_t* result;
result = (*__malloc_hook)(bytes);
return result;
}
#endif
nb = request2size(bytes);
arena_get(ar_ptr, nb);
if(!ar_ptr)
return 0;
victim = chunk_alloc(ar_ptr, nb);
(void)mutex_unlock(&ar_ptr->mutex);
if(!victim) {
/* Maybe the failure is due to running out of mmapped areas. */
if(ar_ptr != &main_arena) {
(void)mutex_lock(&main_arena.mutex);
victim = chunk_alloc(&main_arena, nb);
(void)mutex_unlock(&main_arena.mutex);
}
if(!victim) return 0;
}
return chunk2mem(victim);
}
#define arena_get(ptr, size) do { \
Void_t *vptr = NULL; \
ptr = (arena *)tsd_getspecific(arena_key, vptr); \
if(ptr && !mutex_trylock(&ptr->mutex)) { \
THREAD_STAT(++(ptr->stat_lock_direct)); \
} else \
ptr = arena_get2(ptr, (size)); \
} while(0)
static arena *
#if __STD_C
arena_get2(arena *a_tsd, size_t size)
#else
arena_get2(a_tsd, size) arena *a_tsd; size_t size;
#endif
{
arena *a;
heap_info *h;
char *ptr;
int i;
unsigned long misalign;
if(!a_tsd)
a = a_tsd = &main_arena;
else {
a = a_tsd->next;
if(!a) {
/* This can only happen while initializing the new arena. */
(void)mutex_lock(&main_arena.mutex);
THREAD_STAT(++(main_arena.stat_lock_wait));
return &main_arena;
}
}
/* Check the global, circularly linked list for available arenas. */
do {
if(!mutex_trylock(&a->mutex)) {
THREAD_STAT(++(a->stat_lock_loop));
tsd_setspecific(arena_key, (Void_t *)a);
return a;
}
a = a->next;
} while(a != a_tsd);
/* Nothing immediately available, so generate a new arena. */
h = new_heap(size + (sizeof(*h) + sizeof(*a) + MALLOC_ALIGNMENT));
if(!h)
return 0;
a = h->ar_ptr = (arena *)(h+1);
for(i=0; i<NAV; i++)
init_bin(a, i);
a->next = NULL;
a->size = h->size;
tsd_setspecific(arena_key, (Void_t *)a);
mutex_init(&a->mutex);
i = mutex_lock(&a->mutex); /* remember result */
/* Set up the top chunk, with proper alignment. */
ptr = (char *)(a + 1);
misalign = (unsigned long)chunk2mem(ptr) & MALLOC_ALIGN_MASK;
if (misalign > 0)
ptr += MALLOC_ALIGNMENT - misalign;
top(a) = (mchunkptr)ptr;
set_head(top(a), (((char*)h + h->size) - ptr) | PREV_INUSE);
/* Add the new arena to the list. */
(void)mutex_lock(&list_lock);
a->next = main_arena.next;
main_arena.next = a;
(void)mutex_unlock(&list_lock);
if(i) /* locking failed; keep arena for further attempts later */
return 0;
THREAD_STAT(++(a->stat_lock_loop));
return a;
}
内嵌汇编
VC下内嵌汇编的例子:(Intel汇编语法)
// cmpxchg op1, op2
//
// cmpxchg use al, ax, eax, rax as output.
// if al, ax, eax, rax equals op1, op2 loaded into op1, else, load op2 into al, ax, eax, rax.
short cmpxchg_s(short v_exchange, short* v_ptr, short v_compare)
{
__asm mov edx, v_ptr; // mov v_ptr to edx
__asm mov ax, v_compare; // mov v_compare to ax
__asm mov cx, v_exchange; // mov v_exchange to cx
__asm cmpxchg word ptr [edx], cx;
// below comment code use to get the output of cmpxchg and return. but
// it's is needless. by defult, the last statement's result returned.
// in this case, the output of cmpxchg is returned.
//__asm mov v_exchange, ax;
//return v_exchange;
}
int cmpxchg_sx(short v_exchange, short* v_ptr, short v_compare)
{
return cmpxchg_s(v_exchange, v_ptr, v_compare) == v_compare;
}
int cmpxchg(int v_exchange, int* v_ptr, int v_compare)
{
__asm mov edx, v_ptr; // mov v_ptr to edx
__asm mov eax, v_compare; // mov v_compare to ax
__asm mov ecx, v_exchange; // mov v_exchange to cx
__asm cmpxchg dword ptr [edx], ecx;
// below comment code use to get the output of cmpxchg and return. but
// it's is needless. by defult, the last statement's result returned.
// in this case, the output of cmpxchg is returned.
//__asm mov v_exchange, eax;
//return v_exchange;
}
int cmpxchg_x(int v_exchange, int* v_ptr, int v_compare)
{
return cmpxchg(v_exchange, v_ptr, v_compare) == v_compare;
}
gnulib
参考另一篇文章:https://lobin.iteye.com/blog/609813
ANSI C grammar, Lex specification,http://www.lysator.liu.se/c/ANSI-C-grammar-l.html
https://port70.net/~nsz/c/c11
Programming languages -- C,https://port70.net/~nsz/c/c11/n1570.html
ANSI C Specification,http://eli-project.sourceforge.net/c_html/c.html
Rationale for American National Standard for Information Systems - Programming Language - C,http://www.lysator.liu.se/c/rat/title.html
select & poll
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <sys/socket.h>
#include <poll.h>
#include <sys/time.h>
#include <netinet/in.h>
#include <errno.h>
#include <unistd.h>
#define PORT 6002
//最多处理的connect
#define BACKLOG 5
//当前的连接数
int currentClient = 0;
//数据接受 buf
#define REVLEN 10
char recvBuf[REVLEN];
#define OPEN_MAX 1024
struct pollfd* _fd_init(struct pollfd* const fd_set)
{
struct pollfd *poll_fd_set;
if (fd_set == NULL)
{
poll_fd_set = (struct pollfd *) malloc(OPEN_MAX * sizeof(struct pollfd));
}
else
{
poll_fd_set = fd_set;
}
return poll_fd_set;
}
void _fd_zero(struct pollfd* fd_set)
{
for(int i = 0; i < OPEN_MAX; i++)
{
fd_set[i].fd = -1;
}
}
void _fd_set(int fd, struct pollfd* const fd_set)
{
fd_set[0].fd = fd;
fd_set[0].events = POLLIN; //POLLRDNORM;
}
class SocketException
{
private:
int errorCode;
char *message;
public:
SocketException(int errorCode)
{
this->errorCode = errorCode;
this->message = NULL;
}
SocketException(int errorCode, char *message)
{
this->errorCode = errorCode;
this->message = message;
}
int getCode()
{
return errorCode;
}
char* getMessage()
{
return message;
}
};
class HardSocket
{
private:
int sfd;
public:
HardSocket() throw (SocketException)
{
/**
* On success, a file descriptor for the new socket is returned. On
* error, -1 is returned, and errno is set appropriately.
*/
int fd = socket(AF_INET, SOCK_STREAM, 0);
//fd = -1;
if (fd == -1)
{
int error = errno;
throw SocketException(error);
}
this->sfd = fd;
}
~HardSocket()
{
printf("~HardSocket\n");
}
int getPlainSocket()
{
return this->sfd;
}
void bind(int port) throw (SocketException)
{
struct sockaddr_in server_addr;
bzero(&server_addr, sizeof(server_addr));
server_addr.sin_family = AF_INET;
server_addr.sin_port = htons(port);
server_addr.sin_addr.s_addr = htonl(INADDR_ANY);
int error = ::bind(this->sfd, (struct sockaddr*) &server_addr, sizeof(server_addr));
if(error == -1)
{
error = errno;
throw SocketException(error);
}
}
void listen() throw (SocketException)
{
this->listen(50);
}
void listen(int backlog) throw (SocketException)
{
int error = ::listen(this->sfd, backlog);
if(error == -1)
{
error = errno;
throw SocketException(error);
}
}
};
class Poll
{
};
int main()
{
HardSocket *socket = NULL;
try
{
socket = new HardSocket();
socket->bind(PORT);
socket->listen();
}
catch (SocketException e)
{
printf("socket error %d\n", e.getCode());
// 有问题, 这里实例化一个socket对象时抛出异常的话, 析构函数不会被调用以释放对象资源
//sleep(5000);
return 1;
}
/**
* struct pollfd {
* int fd; // file descriptor
* short events; // requested events
* short revents; // returned events
* };
*/
struct pollfd clientfd[OPEN_MAX];
_fd_zero(clientfd);
_fd_set(socket->getPlainSocket(), clientfd);
int nfds = 0;
while(1)
{
int timeout = 3000;
int error = poll(clientfd, nfds+1, timeout);
if(error < 0) // On error, -1 is returned, and errno is set appropriately.
{
printf("select error %d\n", errno);
break;
}
else if(error == 0) // A value of 0 indicates that the call timed out and no file descriptors were ready.
{
printf("timeout ...\n");
continue;
}
for(int i = 0; i <= nfds; i++)
{
if(clientfd[i].fd < 0)
{
continue;
}
if (clientfd[i].fd == socket->getPlainSocket())
{
/**
* Case indicates that one event that data to read (POLLIN or POLLRDNORM) contained.
*
* // The following values are defined by XPG4.
* #define POLLRDNORM POLLIN
*/
if (clientfd[i].revents & POLLIN)
{
printf("clientfd[%d].revents & POLLIN %d(0x%x) clientfd[%d].revents %d(0x%x), POLLIN %d(0x%x)\n",
i,
clientfd[i].revents & POLLIN,
clientfd[i].revents & POLLIN,
i,
clientfd[i].revents,
clientfd[i].revents,
POLLIN,
POLLIN);
int sockSvr = accept(socket->getPlainSocket(), NULL, NULL);//(struct sockaddr*)&client_addr
if(sockSvr == -1)
{
printf("accpet error\n");
}
else
{
currentClient++;
}
for(i=0; i<OPEN_MAX; i++)
{
if(clientfd[i].fd<0)
{
clientfd[i].fd = sockSvr;
break;
}
}
if(i == OPEN_MAX)
{
printf("too many connects\n");
return -1;
}
clientfd[i].events = POLLIN;//POLLRDNORM;
if(i > nfds)
{
nfds = i;
}
}
}
else if (clientfd[i].revents & (POLLIN | POLLERR)) // POLLRDNORM
{
printf("clientfd[%d].revents & (POLLIN | POLLERR) %d(0x%x) clientfd[%d].revents %d(0x%x), POLLIN %d(0x%x), POLLERR %d(0x%x)\n",
i,
clientfd[i].revents & (POLLIN | POLLERR),
clientfd[i].revents & (POLLIN | POLLERR),
i,
clientfd[i].revents,
clientfd[i].revents,
POLLIN,
POLLIN,
POLLERR,
POLLERR);
int recvLen = 0;
if(recvLen != REVLEN)
{
while(1)
{
printf("recv....\n");
//recv数据
int bytes = recv(clientfd[i].fd, (char *) recvBuf+recvLen, REVLEN - recvLen, 0);
if(bytes == 0)
{
printf("stream socket %d peer has performed an orderly shutdown\n", clientfd[i].fd);
clientfd[i].fd = -1;
recvLen = 0;
break;
}
else if(bytes == -1)
{
printf("receive a message from a socket error %d\n", errno);
clientfd[i].fd = -1;
recvLen = 0;
break;
}
//数据接受正常
recvLen = recvLen + bytes;
if(recvLen < REVLEN)
{
continue;
}
else
{
//数据接受完毕
printf("buf = %s\n", recvBuf);
//close(client[i].fd);
//client[i].fd = -1;
recvLen = 0;
break;
}
}
}
}
}
}
return 0;
}
select
#pragma comment(lib,"ws2_32.lib")
#include <stdio.h>
#include <string.h>
#include <WINSOCK2.H>
#include <log.h>
#include "socket/HardSocket.h"
#include "socket/LightSocket.h"
#include "SelectEvent.hpp"
#define INT_SERVER_PORT 6002
#define STR_SERVER_IP "127.0.0.1"
#define INT_DATABUFFER_SIZE 100
class SelectEventBusinessHandler : public SelectEvent
{
public:
void onAccept(LightSocket &socket)
{
sockaddr_in addr = socket.getSocketAddress();
debug("handle on accept event from %s:%d(socket %d)", inet_ntoa(addr.sin_addr), ntohs(addr.sin_port), socket.getPlainSocket());
}
void onMessage(LightSocket &socket, char *bytes)
{
sockaddr_in addr = socket.getSocketAddress();
//打印接收的数据
info("recv from %s:%d\ndata:%s", inet_ntoa(addr.sin_addr), ntohs(addr.sin_port), bytes);
}
};
class Select : public HardSocket
{
private:
fd_set fd;
SelectEvent* eventHandler;
public:
Select()
{
Socket::init(AF_INET, SOCK_STREAM, 0);
eventHandler = new SelectEventBusinessHandler();
FD_ZERO(&fd);
FD_SET(this->getPlainSocket(), &fd);
}
void select()
{
fd_set fdOld = fd;
//timeval tm;
//tm.tv_sec = 0;
//tm.tv_usec = 1000;
int selected = ::select(0, &fdOld, NULL, NULL, NULL);
if (selected == SOCKET_ERROR)
{
//WSACleanup();
//printf("Faild to select sockt in server!/r/n");
int error = WSAGetLastError();
warn("select error %d", error);
Sleep(100);
}
else if (selected == 0)
{
warn("select error, time limit expired");
}
else
{
for(int i = 0;i < fd.fd_count; i++)
{
SOCKET sfd = fd.fd_array[i];
if (FD_ISSET(sfd, &fdOld))
{
//如果socket是服务器,则接收连接
if (sfd == this->getPlainSocket())
{
onAccept();
}
else //非服务器,接收数据(因为fd是读数据集)
{
onRead(sfd);
}
}
else
{
warn("socket fd %d not in fd set", sfd);
}
}
}
}
void onAccept()
{
sockaddr_in addrAccept;
int so_sockaddr_in = sizeof(sockaddr_in);
memset(&addrAccept, 0, so_sockaddr_in);
SOCKET sockAccept = ::accept(this->getPlainSocket(), (sockaddr *) &addrAccept, &so_sockaddr_in);
if (sockAccept == INVALID_SOCKET)
{
warn("accepted an invalid socket connection");
return;
}
FD_SET(sockAccept, &fd);
//FD_SET(sockAccept,&fdOld);
info("%s:%d has connected server!", inet_ntoa(addrAccept.sin_addr), ntohs(addrAccept.sin_port));
LightSocket *cs = new LightSocket(sockAccept);
cs->setSocketAddress(addrAccept);
eventHandler->onAccept(*cs);
}
void onRead(SOCKET sfd)
{
char szDataBuff[INT_DATABUFFER_SIZE];///////
memset(szDataBuff, 0, INT_DATABUFFER_SIZE);
szDataBuff[INT_DATABUFFER_SIZE - 1] = '\0';
int bytes = recv(sfd, szDataBuff, INT_DATABUFFER_SIZE - 1, 0);
sockaddr_in addr;
int so_sockaddr_in = sizeof(sockaddr_in);
memset(&addr, 0, so_sockaddr_in);
getpeername(sfd, (sockaddr *) &addr, &so_sockaddr_in);
if (bytes == SOCKET_ERROR)
{
int error = WSAGetLastError();
warn("Fail to receive data from %s:%d error %d", inet_ntoa(addr.sin_addr), ntohs(addr.sin_port), error);
closesocket(sfd);
FD_CLR(sfd, &fd);
//i--;
return;
}
if (bytes == 0)
{
//客户socket关闭
warn("%s:%d has closed!", inet_ntoa(addr.sin_addr), ntohs(addr.sin_port));
closesocket(sfd);
FD_CLR(sfd, &fd);
//i--;
}
if (bytes > 0)
{
LightSocket *cs = new LightSocket(sfd);
cs->setSocketAddress(addr);
eventHandler->onMessage(*cs, szDataBuff);
}
}
};
void main(void)
{
///*
Select *socket = new Select();
bool bReuseAddr = true;
socket->setSocketOption(SOL_SOCKET, SO_REUSEADDR, (char *) &bReuseAddr, sizeof(bReuseAddr));
//unsigned long cmd = 1;
//iResult= ioctlsocket(sockServer,FIONBIO,&cmd);
socket->bind(INT_SERVER_PORT);
socket->listen(5);
info("Start server...");
while(1)
{
socket->select();
}
WSACleanup();
}
开发自己的C运行库及标准库
https://www.iteye.com/blog/lobin-620212
相关推荐
C语言运行时库C语言运行时库C语言运行时库C语言运行时库C语言运行时库C语言运行时库C语言运行时库C语言运行时库C语言运行时库C语言运行时库C语言运行时库C语言运行时库C语言运行时库C语言运行时库C语言运行时库C语言...
- **动态库加载**: 动态库在运行期间被加载到进程的地址空间中,这种机制允许多个进程共享相同的库实例,从而节省了内存资源并提高了系统性能。 **2. 编程技巧** - **代码优化**: 书中通过具体的示例介绍了一些...
- CRT(C Run-Time Library):C语言运行时库,提供基本的输入/输出、内存管理和数学运算等功能。 - STL(Standard Template Library):C++标准模板库,包含容器、迭代器和算法等。 **4. 安装与更新** 为了确保...
VS2013运行库中的msvcr120.dll是C运行时库的一部分,用于支持C++代码的执行。 2. **性能优化**:运行库通常经过了高度优化,能够提高应用程序的运行效率,减少资源消耗。 3. **跨平台兼容**:对于开发者而言,使用...
C语言运行库,通常被称为C Run-Time Library (CRT),是C编程语言不可或缺的一部分。它包含了一系列函数和数据结构,使得C程序能够在操作系统上正确地执行。《程序员的自我修养》一书中,作者深入剖析了C语言运行库的...
**VC运行库2011**是微软Visual C++开发工具的一个重要组成部分,它为基于C++编程语言的软件提供必要的运行环境。这些运行库包含了编译器生成的动态链接库(DLLs),使得计算机在运行使用Visual C++开发的应用程序时...
这个“常用运行库”包的就是为了解决这类问题而生的,原版系统自带的运行库比较旧且数量少,而这个包则涵盖了目前各个版本的运行库和常用的控件,可以起到增强系统的作用。 这是装完系统后必装的东西,就像Flash...
**VC 6运行库(MFC 4.2运行库)** VC 6运行库是Microsoft Visual C++ 6.0版本的一部分,它包含了用于支持C++应用程序执行所必需的动态链接库(DLL)。这些库使得开发人员可以利用微软的MFC (Microsoft Foundation ...
VB6.0运行库是微软Visual Basic 6.0编程环境中不可或缺的一部分,它包含了执行VB6编译程序所需的关键组件。这些组件主要是动态链接库(DLL)文件,用于支持VB6应用程序的运行。在本例中,我们有两个重要的DLL文件:...
**VC6 MFC运行库详解** ...总的来说,VC6 MFC运行库是支持使用VC6开发的MFC程序运行所必需的组件,包括MFC核心库文件、C运行时库文件等。在部署和维护这些程序时,理解这些库的作用和依赖关系至关重要。
VC运行库是Windows环境下开发应用程序的关键组件,尤其对于使用Visual C++编译器的开发者而言,它是必不可少的。这些库提供了许多系统级别的功能,使得软件能够顺利地在不同版本的Windows操作系统上运行,如Win7和...
Microsoft Visual C++运行库合集由国外网友McRip制作,包含了VC2005、VC2008、VC2010、VC2012运行库,包含32及64位版本。这些运行库都是采用Microsoft Visual Studio 20XX编写的软件必须使用的公用DLL运行库。网上...
C++运行库是许多基于C++开发的软件运行的基础,因为它们包含了运行这些程序所需的动态链接库(DLL)和其他系统组件。"必备C++运行库合集.rar"这个压缩包很可能是为了帮助用户解决在执行某些C++应用程序时遇到的依赖...
1. C和C++标准库:提供基本的数据类型、输入/输出流、字符串处理、内存管理等功能。 2. C++异常处理:用于错误处理,当程序遇到异常情况时可以进行适当的响应。 3. 多线程支持:在多处理器或多核心系统中并行执行...
微软C++运行库是开发和运行使用Microsoft Visual C++编译器创建的应用程序所必需的一组共享库。这些库包含了各种函数和类,为开发者提供了许多功能,包括内存管理、输入输出、线程处理等。当您遇到某些应用程序因为...
ANTLR C语言运行时库是ANTLR解析器生成器在C语言中的实现,它提供了一套API和数据结构,使得开发者能够方便地在C程序中嵌入ANTLR生成的解析器。这个库允许你在C项目中解析ANTLR生成的语法文法,处理输入的语句或数据...
4. CRT (C Run-Time Library):提供了C语言运行时的基本功能,如内存分配、字符串处理等。 5. STL (Standard Template Library):C++标准库的一部分,包含容器、迭代器和算法等模板类。 6. PDB (Program Database)...
VS 2015运行库包含了各种C++运行时库,如MFC(Microsoft Foundation Classes)、ATL(Active Template Library)以及C运行时(CRT),它们是C++编程中广泛使用的库。 描述中提到的“解决import过程中提示的没有指定...
5. **使用lib文件**:最后,编写另一个C语言程序`show.c`,并在其中调用`goodluck()`函数: ```c #include int main() { clrscr(); /**/ goodluck(); return 0; } ``` 使用`tlink.exe`链接器链接`show.c...
4. **CRT(C Run-Time Library)**:提供C语言的基本运行时功能,如内存分配、输入输出、字符串处理等。 5. **OpenMP**:并行计算框架,支持多线程编程。 在安装VC9运行库时,需要注意以下几点: - 安装过程中应...