c实现"对象"
来源:互联网 发布:python readline 编辑:程序博客网 时间:2024/06/05 14:33
后来看到了此博客http://blog.csdn.net/ghostyu/article/details/7921179
也是通过c结构体相互引用来实现的。
标题不好取,所以再啰嗦补充下,等以后想到好的表述了再更改。
在dvr项目中,不同的chip初始化和设置也是不同的,例如gm8187/gm8210等。这些初始化都是以以库的形式出现的,所以用c来实现。之前没有融入"对象"的概念之前,
一般的实现就是if/else或者switch/case来兼容不同的产品,每次有新的设置都会在有差异的地方修改代码。
一、c的"对象"
大概形态,要包含函数指针
{
int a;
void (*pfunc)(void);
}
二、实际实现
就是参考的ffmpeg里的enc/dec 注册来实现的。
待续
接上,给出精彩的代码。
#ifdef __cplusplusextern "C"{#endif#include <stdio.h> #include <string.h> #include <stdlib.h>#include <unistd.h>#include <sys/ioctl.h>#include <sys/time.h>#include <fcntl.h>#if1//来自ffmpeg,祛除了些变量typedef int offset_t;#ifdef ENOENT#undef ENOENT#endif#define ENOENT 2#ifdef ENOMEM#undef ENOMEM#endif#define ENOMEM 12#define URL_RDONLY 0#define URL_WRONLY 1#define URL_RDWR 2#define INT_MAX 2147483647#define FFMAX(a,b) ((a) > (b) ? (a) : (b))void *av_malloc(unsigned int size){ void *ptr; if (size > INT_MAX) return NULL; ptr = malloc(size); return ptr;}void *av_realloc(void *ptr, unsigned int size){ if (size > INT_MAX) return NULL; return realloc(ptr, size);}void av_free(void *ptr){ if (ptr) free(ptr);}//具体和抽象通过指针互相引用来建立联系//对客户/调用角度来看,只关心抽象(URLProtocol)即可//具体的实现都可以封装为.a,详情看本demo代码//抽象typedef struct URLContext{ struct URLProtocol *prot; int flags; int max_packet_size; // if non zero, the stream is packetized with this max packet size void *priv_data; char filename[1]; // specified filename} URLContext;//具体typedef struct URLProtocol{ const char *name; int(*url_open)(URLContext *h, const char *filename, int flags); int(*url_read)(URLContext *h, unsigned char *buf, int size); int(*url_write)(URLContext *h, unsigned char *buf, int size); offset_t(*url_seek)(URLContext *h, offset_t pos, int whence); int(*url_close)(URLContext *h); struct URLProtocol *next;} URLProtocol;#endif/////////////////////////////////以下以应用代码来演示,为了方便,就放在一个.c中了//抽象typedef struct DVRContext{ struct DVRProduct *prot; int flags; int max_packet_size; // if non zero, the stream is packetized with this max packet size void *priv_data;int type; char dvrname[1]; // specified filename} DVRContext;//具体typedef struct DVRProduct{ const char *name; int(*dvr_open)(DVRContext *h, const char *filename, int flags); int(*dvr_read)(DVRContext *h, unsigned char *buf, int size); int(*dvr_write)(DVRContext *h, unsigned char *buf, int size); int(*dvr_close)(DVRContext *h); struct DVRProduct *next;} DVRProduct;//带gm8210的单独放在gm8210.c中,其他gmxx仿写gm8210即可//gm8210_open/gm8210_read等沿用了ffmpeg里的URLProtocol,仅demostatic int gm8210_open(DVRContext *h, const char *filename, int flags){printf("gm8210_open,%s jiu zheyang bei ni open\n",h->dvrname); int access; int fd;access = O_CREAT | O_TRUNC | O_RDWR;fd = open(filename, access, 0666); if (fd < 0) { return - ENOENT; }//可以看出,priv_data就是具体对象的私有数据,此处为fd//不同的具体对象可以用不同的私有数据,依赖自己的应用 h->priv_data = (void*)(size_t)fd; return 0;}static int gm8210_read(DVRContext *h, unsigned char *buf, int size){ int fd = (size_t)h->priv_data; return read(fd, buf, size);}static int gm8210_write(DVRContext *h, unsigned char *buf, int size){ int fd = (size_t)h->priv_data; return write(fd, buf, size);}static int gm8210_close(DVRContext *h){printf("gm8210_close,%s jiu zheyang bei ni close\n",h->dvrname); int fd = (size_t)h->priv_data; return close(fd);}DVRProduct gm8210_dvr ={ "gm8210",gm8210_open,gm8210_read,gm8210_write,gm8210_close,};//8287static int gm8287_open(DVRContext *h, const char *filename, int flags){printf("gm8287_open,%s jiu zheyang bei ni open\n",h->dvrname); int access; int fd;access = O_CREAT | O_TRUNC | O_RDWR;fd = open(filename, access, 0666); if (fd < 0) { return - ENOENT; } h->priv_data = (void*)(size_t)fd; return 0;}static int gm8287_close(DVRContext *h){printf("gm8287_close,%s jiu zheyang bei ni close\n",h->dvrname); int fd = (size_t)h->priv_data; return close(fd);}DVRProduct gm8287_dvr ={ "gm8287",gm8287_open,NULL,NULL,gm8287_close,};DVRProduct *first_dvr = NULL;//也可以不创建链表,直接first_dvr = gmxx_dvrint register_product(DVRProduct *pdvr){ DVRProduct **pp; pp = &first_dvr; while (*pp != NULL) { pp = &(*pp)->next; } *pp = pdvr; pdvr->next = NULL; return 0;}int gmdvr_open(DVRContext **puc, const char *filename, int flags){ DVRContext *uc; DVRProduct *up; const char *p; int err; p = filename; up = first_dvr; while (up != NULL) { if (!strcmp(p, up->name)) { goto found;//找到对应的 } up = up->next; } err = -ENOENT; goto fail;found: uc = av_malloc(sizeof(DVRContext) + strlen(filename)); if (!uc) { err = - ENOMEM; goto fail; }//抽象/具体关联 strcpy(uc->dvrname, filename); uc->prot = up; uc->flags = flags; uc->max_packet_size = 0; // default: stream file err = up->dvr_open(uc, filename, flags);//具体的gmxx_dvr.dvr_open if (err < 0) { av_free(uc); *puc = NULL; return err; } *puc = uc;//带出已确定的上下文(抽象) return 0;fail:*puc = NULL; return err;}DVRContext *g_dvrctx = NULL;int gmdvr_getctx(const char *filename){if(!g_dvrctx){return -1;} const char *p; p = filename;if (!strcmp(p, g_dvrctx->dvrname)) { printf("gmdvr_getctx,for %s\n",g_dvrctx->dvrname);return 0; }else{return -2;}return 0;}int gmdvr_init(const char *filename){ int err;err = gmdvr_open(&g_dvrctx, filename, URL_RDWR); if (err < 0) { return err; }return 0;}int gmdvr_uninit(const char *filename){ int err;err = gmdvr_getctx(filename);if (err < 0) { return err; }g_dvrctx->prot->dvr_close(g_dvrctx);return 0;} int main(int argc, char* argv[]){//可以全部注册好 register_product(&gm8210_dvr); register_product(&gm8287_dvr);//char* name/int id来自上层app,或者register && init都可以暴露给上层appgmdvr_init("gm8210");gmdvr_uninit("gm8210");printf("\n#########\n");gmdvr_init("gm8287");gmdvr_uninit("gm8287");return 0;}#ifdef __cplusplusextern "C"}#endif
重新思考了下,感觉应该是这样的
DVRContext //抽象
DVRProduct //具体
- c实现面向对象
- c实现"对象"
- c实现面向对象
- c实现面向对象
- c实现面向对象
- C实现面向对象
- C实现面向对象
- C实现面向对象
- 汇编+c 实现面向对象
- c 指针实现面向对象
- c语言实现面向对象
- C语言实现面向对象
- 用c实现面向对象
- C语言实现面向对象
- C语言实现面向对象
- C语言实现面向对象
- 用C实现面向对象
- C语言实现面向对象
- Visual Studio:error MSB8020
- android下载指定的文件
- 含有三角函数的不等式
- CodeBlocks MinGW Windres 资源文件支持中文
- 男朋友就是你早晨醒来时第一个想到的那个人
- c实现"对象"
- 并发和同步
- 类型 SoftReference 不带有参数
- flex bulider 4新建java web应用
- uva 644 immediately
- Java Spring Tutorial -- List, Set, & Map Injection
- 在 SharePoint 2010 中访问数据
- 三情과 生活과의 關係
- linux下发各种协议包及其详细分析