假设我们有一个功能:
void persist_result(FILE* to, unsigned char* b, int b_len) {...}
可以在给定的FILE* to
中保存一些结果。
现在我希望在将数据写入to
之前获取数据,对其执行某些操作(假设加密等等),然后直接或间接调用实际的IO操作。
一种解决方案可能是设置缓冲区,但我不知道如何触发加密操作的方法。
另外我想在内存中获取一些文件句柄,但不知道是否有任何ISO方法可以做到这一点?
还是更好的解决方案?
请考虑以下事项:
persist_result
需要写入的数据大小未知,可能是1个或更多字节。persist_result
。答案 0 :(得分:0)
您要找的是Observer Pattern。 调用函数时,实际上您可以先捕获该调用,执行您喜欢的操作,然后继续执行您正在执行的操作。您可以使用指向函数的指针在C中实现它。
您可以从以下example
中获取灵感答案 1 :(得分:0)
在不更改呼叫的情况下,无法捕获标准C中的每个操作。像加密这样的东西需要上下文(如关键)才能工作;这会使生活变得复杂,但也许persist_result()
会自动处理。您将如何处理fseek()
或rewind()
?
我认为除非您将I / O操作写入非标准的C API,以便您能够干净利落地完成所需的操作,否则我会陷入痛苦的世界。例如,您的代码可能会被写入调用函数,例如pr_fwrite()
,pr_putc()
,pr_fprintf()
,pr_vfprintf()
,pr_fseek()
,pr_rewind()
等 - 你可能不会将它应用于stdin或stdout - 并让那些人做必要的事情。
如果我要尝试此操作,我会采用前缀(pr_
和PR
)并创建一个标题"prstdio.h"
来代替或另外使用到,<stdio.h>
。它可以包含(以及评论和标题保护等):
#include <stdarg.h>
// No need for #include <stdio.h>
typedef struct PRFILE PRFILE;
extern PRFILE *pr_fopen(const char *name, const char *mode);
extern int pr_fclose(PRFILE *fp);
extern int pr_fputc(char c, PRFILE *fp);
extern size_t pr_fwrite(const void *buffer, size_t size, size_t number, PRFILE *fp);
extern int pr_fprintf(PRFILE *fp, char *fmt, ...);
extern int pr_vfprintf(PRFILE *fp, char *fmt, va_list args);
extern int pr_fseek(PRFILE *fp, long offset, int whence);
extern void pr_rewind(PRFILE *fp);
…
并且需要使用persist_result()
函数的所有现有I / O调用都将被编写为使用prstdio.h
接口。在您的实现文件中,您实际定义了结构struct PRFILE
,其中包括FILE *
成员以及您需要的任何其他信息。然后,您可以编写这些pr_*
函数来执行必要的操作,并且需要保留结果的代码更改为调用pr_*
函数(并使用PRFILE *
类型)您目前使用stdio.h
函数。
这样做的优点是可以简单地符合C标准,并且可以移植。此外,对现有代码的更改需要使用“持久性结果”&#39;图书馆非常系统化。
在主要问题的comment中 - 最初回应我现在删除的评论(其中的内容现在在此答案中) - OP问:
我需要在普通数据写操作之前进行加密操作。加密上下文已准备就绪。我在考虑在内存上使用磁盘,但是它是否也可以在Android NDK和iOS中使用?
到目前为止,您的讨论是加密和写入数据。别忘了I / O方程的另一半 - 读取和解密数据。您需要在标头中使用适当的输入函数才能处理它。 pr_ungetc()
函数可能会引起一些有趣的讨论。
此处列出的方案可用于您可以编写C代码的其他系统。它不依赖任何非标准的东西。这是在C中实现数据隐藏的合理方法。只有prstdio
库的实现文件需要了解PRFILE
结构的内部结构。
因为内存中的磁盘&#39;不是标准C的一部分,任何使用这种概念的代码都必须使用非标准C.你需要仔细考虑它对于可移植性等意义。然而,prstdio
的外部接口库可能与此处描述的大致相同,除了您可能需要一个或多个控制函数来操作数据在内存中的位置。或者您可以修改pr_fopen()
以获取控制内存管理的额外参数。这将是你的决定。但是,通用I / O接口不需要改变。