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语言...
这个“常用运行库”包的就是为了解决这类问题而生的,原版系统自带的运行库比较旧且数量少,而这个包则涵盖了目前各个版本的运行库和常用的控件,可以起到增强系统的作用。 这是装完系统后必装的东西,就像Flash...
Microsoft Visual C++运行库合集由国外网友McRip制作,包含了VC2005、VC2008、VC2010、VC2012等运行库,包含32及64位版本。这些运行库都是采用Microsoft Visual Studio 20XX编写的软件必须使用的公用DLL运行库。网上...
运行库大全 Visual C++ 2005 运行库(x86) 8.0.61187........1 Visual C++ 2005 运行库(x64) 8.0.61186.........2 Visual C++ 2008 运行库(x86) 9.0.30729.7523.....3 Visual C++ 2008 运行库(x64) 9.0.30729.7523......
版本号 发布日期 主要的变化 0.9 07-01-04 初始版本 0.9a 07-06-04 1)整本书改用16开本进行排版,页数因此有所改变 2)所有命令的名字用不同的字体明确标识出来 ...3)补充关于动态库代码在运行期被载入程序映射进
C++运行库大全
提示缺少C++运行库的朋友们可以下载安装!
《程序员的自我修养》C语言运行库实现代码,在Windows环境下编译通过。
第二部分为运行库参考,包括运行库例程分类、全局变量和标准类型、全局常量、调试版C运行库和运行类库字母顺序参考等五章。全书结构合理、文字简洁流畅且方便易查。它是从事Visual C++ 6.0 应用与开发的技术人员必备...
Microsoft Visual C++运行库合集由国外网友McRip制作,包含了VC2005、VC2008、VC2010、VC2012运行库,包含32及64位版本。这些运行库都是采用Microsoft Visual Studio 20XX编写的软件必须使用的公用DLL运行库。网上...
vc2012_x64运行库VC2012运行库Visual C++ 2012 Redistributable Package 安装 Visual C++ 库的运行时组件,这些组件是在未安装 Visual Studio 2012 的计算机上运行使用 Visual Studio 2012 开发的应用程序所必需的。...
这些运行库都是采用Microsoft Visual Studio 20XX编写的软件必须使用的公用DLL运行库,相当于程序的字典文件。 某些网上和论坛的部分精简软件没有附带这些公用DLL,所以安装这些运行库是系统安装后第一件要做的事情...
antlr C语言运行时库; antlr C语言运行时库; antlr C语言运行时库
最近在学习计算机图形学,所以我整理了用到的三种openGL运行库,包含了传统的C语言下的openGL运行库,和C#下(.NET 2.0)的openGL运行库SharpGL和C#(.NET 4.0)下的openGL运行库文件,还附带一本讲解超详细的NeHe中文版...
如果网友对电脑系统熟悉的都知道,我们平进使用软件都是Microsoft Visual Studio 编写的,所以这类软件的运行需要依赖微软Visual C++运行库,比如像 QQ、迅雷、Adobe 软件等等,如果没有安装VC++运行库或者安装的...
本集合包含下列组件: Visual Basic Virtual Machine(5.1) Visual Basic Virtual Machine (6.0) ...这些运行库都是采用Microsoft Visual Studio 20XX编写的软件必须使用的公用DLL运行库,相当于程序的字典文件。
Windows微软常用运行库合集,这些运行库都是采用Microsoft Visual Studio 20XX编写的软件必须使用的公用DLL运行库,相当于程序的字典文件,某些网上和论坛的部分精简软件没有附带这些公用DLL,相信使用windows的朋友...
VB6.0运行库 将ZIP解压后,放在系统盘(C:)下WINDOWS\SYSTEM32下即可。
Microsoft Visual C++ ...此版Visual C++运行库组件合集(微软常用运行库合集)由国内封装爱好者@Dreamcast打包而成,整合Visual C ++组件安装包运行库所有版本,提供图形安装界面,可自选更新VC++版本。