- android - 多次调用 OnPrimaryClipChangedListener
- android - 无法更新 RecyclerView 中的 TextView 字段
- android.database.CursorIndexOutOfBoundsException : Index 0 requested, 光标大小为 0
- android - 使用 AppCompat 时,我们是否需要明确指定其 UI 组件(Spinner、EditText)颜色
所以我第 64 次尝试编写缓冲库,并且我开始涉足一些非常高级的东西。我想就此征求一些专业意见。
在我的第一个头文件中我有这个:
typedef struct StdBuffer { void* address; } StdBuffer;
extern void StdBufferClear(StdBuffer);
在 #includes
第一个头文件的另一个头文件中,我有这个:
typedef struct CharBuffer { char* address; } CharBuffer;
void (*CharBufferClear)(CharBuffer) = (void*) StdBufferClear;
将此函数指针声明为void 会干扰调用吗?它们具有按值签名匹配。我以前从未见过声明为 void 的函数指针,但这是让它干净地编译的唯一方法。
从堆栈上看,它与我在汇编代码中学到的东西应该没有任何区别。
无关紧要天哪!我刚刚在 StackOverflow 上说过 Stackwise!
嗯.. 看来我在这里假设太多了。如果可以,请允许我再次澄清。我不在乎地址中存储的是什么“类型”的数据。我所关心的只是一个“单元”的大小以及该地址有多少个单元。如果您愿意,请查看 API 的接口(interface)协议(protocol)契约(Contract):
typedef struct StdBuffer {
size_t width; ///< The number of bytes that complete a data unit.
size_t limit; ///< The maximum number of data units that can be allocated for this buffer.
void * address; ///< The memory address for this buffer.
size_t index; ///< The current unit position indicator.
size_t allocated; ///< The current number of allocated addressable units.
StdBufferFlags flags;///< The API contract for this buffer.
} StdBuffer;
你看,memcpy、memmove 和类似的东西并不真正关心地址中的内容,他们想要的只是我在这里清楚地跟踪的细节。
现在看看第一个遵循这个契约的原型(prototype):
typedef struct CharBuffer {
size_t width; ///< The number of bytes that complete a data unit.
size_t limit; ///< The maximum number of data units that can be allocated for this buffer.
char * address; ///< The memory address for this buffer.
size_t index; ///< The current unit position indicator.
size_t allocated; ///< The current number of allocated addressable units.
CharBufferFlags flags;///< The API contract for this buffer.
} CharBuffer;
如您所见,数据类型在此上下文中无关紧要。你可以说 C 会根据不同的情况对其进行不同的处理,但归根结底,一个 address
就是一个 address
,一个 byte
是 byte
而 long
是 long
因为我们在同一台机器上处理内存。
这个系统组合在一起的目的是消除所有这种基于类型的杂耍,C 似乎为此感到自豪(而且理所当然......)它对我想做的事情毫无意义。这是为位于任何地址的任何标准大小的数据(1、2、4、8、sizeof(RandomStruct))创建一个遵守契约(Contract)的原型(prototype)。
能够使用代码执行我自己的转换并使用 api 函数操作该数据,这些函数在具有特定长度内存单元的特定长度内存块上运行。然而,原型(prototype)必须包含正式的数据指针类型,因为对于最终用户来说,每次他们想使用该地址指针做某事时都必须重新转换他们的数据是没有意义的。如果指针为空,将其称为 CharBuffer 是没有意义的。
StdBuffer
是一种通用类型,除了在 api 本身之外从未使用过,用于管理所有遵守契约(Contract)的数据类型。
该系统将包含的 API 来 self 最新版本的缓冲。这里有很清楚的记录 @Google Code我知道有些事情需要改变才能将所有这些整合在一起,即如果没有大量适当的研究和意见收集,我将无法直接从 API 中安全地操作数据。
这引起了我的注意,我还需要 StdBufferFlags 成员中的有符号/无符号位标志。
也许这个拼图的最后一 block 也是为了让您仔细阅读。
/** \def BIT(I)
\brief A macro for setting a single constant bit.
*
* This macro sets the bit indicated by I to enabled.
* \param I the (1-based) index of the desired bit to set.
*/
#define BIT(I) (1UL << (I - 1))
/** \enum StdBufferFlags
\brief Flags that may be applied to all StdBuffer structures.
* These flags determine the contract of operations between the caller
* and the StdBuffer API for working with data. Bits 1-4 are for the
* API control functions. All other bits are undefined/don't care bits.
*
* If your application would like to use the don't care bits, it would
* be smart not to use bits 5-8, as these may become used by the API
* in future revisions of the software.
*/
typedef enum StdBufferFlags {
BUFFER_MALLOCD = BIT(1), ///< The memory address specified by this buffer was allocated by an API
BUFFER_WRITEABLE = BIT(2), ///< Permission to modify buffer contents using the API
BUFFER_READABLE = BIT(3), ///< Permission to retrieve buffer contents using the API
BUFFER_MOVABLE = BIT(4) ///< Permission to resize or otherwise relocate buffer contents using the API
}StdBufferFlags;
最佳答案
此代码需要诊断:
void (*CharBufferClear)(CharBuffer) = (void*) StdBufferClear;
您正在将一个 void *
指针转换为一个没有转换的函数指针。在 C 中,void *
指针可以转换为指向对象类型的指针而无需强制转换,但不能转换为函数指针类型。 (在 C++ 中,为了增加安全性,还需要强制转换将 void *
转换为对象类型。)
你在这里想要的只是在函数指针类型之间进行转换,即:
void (*CharBufferClear)(CharBuffer) = (void (*)(CharBuffer)) StdBufferClear;
那么你仍然在做相同的类型双关,因为函数是不同的类型。您正在尝试使用指向采用 CharBuffer
的函数的指针来调用采用 StdBuffer
的函数。
这种类型的代码不是定义良好的 C。打败了类型系统后,您只能靠自己,依靠测试、检查目标代码,或者从编译器编写者那里获得一些此类事情有效的保证使用那个编译器。
您在汇编代码中学到的知识并不适用,因为汇编语言只有少量基本数据类型,例如“机器地址”或“32 位字”。具有相同布局和低级表示的两个数据结构可能是不兼容类型的概念不会出现在汇编语言中。
即使两种类型在底层看起来相同(另一个例子:unsigned int
和 unsigned long
有时完全相同)C 编译器可以基于没有违反类型规则的假设。例如,假设 A
和 B
指向相同的内存位置。如果您分配给对象 A->member
,C 编译器可以假定对象 B->member
不受此影响,如果 A->member
和 B->member
有不兼容的类型,比如一个是 char *
而另一个是 void *
。生成的代码一直在寄存器中缓存 B->member
的旧值,即使内存中的副本已被分配给 A->member
覆盖。这是无效别名的示例。
关于c - 将函数指针转换为 void 有什么影响?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/10305192/
我正在尝试将一个字符串逐个字符地复制到另一个字符串中。目的不是复制整个字符串,而是复制其中的一部分(我稍后会为此做一些条件......) 但我不知道如何使用迭代器。 你能帮帮我吗? std::stri
我想将 void 指针转换为结构引用。 结构的最小示例: #include "Interface.h" class Foo { public: Foo() : mAddress((uint
这有点烦人:我有一个 div,它从窗口的左上角开始过渡,即使它位于文档的其他任何位置。我试过 usign -webkit-transform-origin 但没有成功,也许我用错了。有人可以帮助我吗?
假设,如果将 CSS3 转换/转换/动画分配给 DOM 元素,我是否可以检测到该过程的状态? 我想这样做的原因是因为我正在寻找类似过渡链的东西,例如,在前一个过渡之后运行一个过渡。 最佳答案 我在 h
最近我遇到了“不稳定”屏幕,这很可能是由 CSS 转换引起的。事实上,它只发生在 Chrome 浏览器 上(可能还有 Safari,因为一些人也报告了它)。知道如何让它看起来光滑吗?此外,您可能会注意
我正在开发一个简单的 slider ,它使用 CSS 过渡来为幻灯片设置动画。我用一些基本样式和一些 javascript 创建了一支笔 here .注意:由于 Codepen 使用 Prefixfr
我正在使用以下代码返回 IList: public IList FindCodesByCountry(string country) { var query =
如何设计像这样的操作: 计算 转化 翻译 例如:从“EUR”转换为“CNY”金额“100”。 这是 /convert?from=EUR&to=CNY&amount=100 RESTful 吗? 最佳答
我使用 jquery 组合了一个图像滚动器,如下所示 function rotateImages(whichHolder, start) { var images = $('#' +which
如何使用 CSS (-moz-transform) 更改一个如下所示的 div: 最佳答案 你可以看看Mozilla Developer Center .甚至还有例子。 但是,在我看来,您的具体示例不
我需要帮助我正在尝试在选中和未选中的汉堡菜单上实现动画。我能够为菜单设置动画,但我不知道如何在转换为 0 时为左菜单动画设置动画 &__menu { transform: translateX(
我正在为字典格式之间的转换而苦苦挣扎:我正在尝试将下面的项目数组转换为下面的结果数组。本质上是通过在项目第一个元素中查找重复项,然后仅在第一个参数不同时才将文件添加到结果集中。 var items:[
如果我有两个定义相同的结构,那么在它们之间进行转换的最佳方式是什么? struct A { int i; float f; }; struct B { int i; float f; }; void
我编写了一个 javascript 代码,可以将视口(viewport)从一个链接滑动到另一个链接。基本上一切正常,你怎么能在那里看到http://jsfiddle.net/DruwJ/8/ 我现在的
我需要将文件上传到 meteor ,对其进行一些图像处理(必要时进行图像转换,从图像生成缩略图),然后将其存储在外部图像存储服务器(s3)中。这应该尽可能快。 您对 nodejs 图像处理库有什么建议
刚开始接触KDB+,有一些问题很难从Q for Mortals中得到。 说,这里 http://code.kx.com/wiki/JB:QforMortals2/casting_and_enumera
我在这里的一个项目中使用 JSF 1.2 和 IceFaces 1.8。 我有一个页面,它基本上是一大堆浮点数字段的大编辑网格。这是通过 inputText 实现的页面上的字段指向具有原始值的值对象
ScnMatrix4 是一个 4x4 矩阵。我的问题是什么矩阵行对应于位置(ScnVector3),旋转(ScnVector4),比例(ScnVector3)。第 4 行是空的吗? 编辑: 我玩弄了
恐怕我是 Scala 新手: 我正在尝试根据一些简单的逻辑将 Map 转换为新 Map: val postVals = Map("test" -> "testing1", "test2" -> "te
输入: This is sample 1 This is sample 2 输出: ~COLOR~[Green]This is sample 1~COLOR~[Red]This is sam
我是一名优秀的程序员,十分优秀!