C 使用void*参数传递整数或指针

C 使用void*参数传递整数或指针,c,pointers,variant,C,Pointers,Variant,我想检测void*类型输入函数参数的值是整数还是指针。目前,我只传递整数(这是Midnight Commander源代码): 但是,我有时也希望在同一个参数中传递一个字符串(char*),因为扩展API会很困难。我知道这是错误的,但是,也许有一个完全合法的方式来获得这种效果?我的想法是: –地址通常与4或8字节对齐,因此我可以从clip_id中跳过这些值(跳过它们),然后解码这些值如果(数据%8),则剪辑id=解码剪辑id(数据)? –也许指针不能小到10…20,一个简单的检查就足够了? –其他

我想检测void*类型输入函数参数的值是整数还是指针。目前,我只传递整数(这是Midnight Commander源代码):

但是,我有时也希望在同一个参数中传递一个字符串(char*),因为扩展API会很困难。我知道这是错误的,但是,也许有一个完全合法的方式来获得这种效果?我的想法是: –地址通常与4或8字节对齐,因此我可以从clip_id中跳过这些值(跳过它们),然后解码这些值<代码>如果(数据%8),则剪辑id=解码剪辑id(数据)? –也许指针不能小到10…20,一个简单的检查就足够了?
–其他想法…?

这样的问题可以通过包含并集和标记的结构来解决

struct EventData {
    enum { EV_IS_INT, EV_IS_PTR } type;
    union {
        intptr_t v_int;
        void * v_ptr;
    };
};
因此,您可以传递一个指向此
EventData
的指针,回调可以根据
type
的值解码是访问
v_int
还是
v_ptr

    struct EventData *ed = makeEventData (EV_IS_INT, clip_id);
    mc_event_raise (MCEVENT_GROUP_CORE, 
                    "clipboard_file_from_ext_clip",
                    ed);

如果事件是异步完成的,您可能需要动态创建事件,然后回调函数必须在使用参数完成回调时释放内存。

Windows使用其句柄和资源ID进行了大量此类攻击

您的整数需要有一个定义的有效范围。超出该范围的任何内容都可能是指针

几乎所有操作系统都保留低内存区域。您可能会假设16位范围0到65535不是指针。除此之外,还有疑问

如果您的代码需要可移植到嵌入式RTO或独立式环境中,那么您不能对指针做任何假设


在任何情况下,您都可能需要某种函数来创建传递到void*中的值,该函数将具有一个
assert
abort
,以避免意外创建无效值。

向上投票,但0是一个有效的整数值和指针值。@jxh是的,假设的
clip\u id\u from\u string
如果传递了一个空指针值,则应该调用
abort
。下一个问题:我有一个参数,有时是int,有时是指针:我如何区分差异?你所有的想法以前都在实际软件中使用过,非常可靠。Windows一直在使用它们。但是你有多在乎你的程序是否能在更奇特的计算机上工作呢?谢谢,这是一个很好的解决方案(除非它有一些缺陷,我目前还没有看到)。我会在某个时候迁移到这个方法,但我的解决方法不同:我知道void*将是char*并且我要传递的整数将很小,最大值为30。因此,我将两个相同的指针传递给一个char。然后我只看第一个字节,检查它是否小于30,如果小于30,这意味着它是整数。此外,char*字符串必须以/(它是一个绝对路径)代码47开头。因此,解决方案是完全可靠的。
    struct EventData *ed = makeEventData (EV_IS_INT, clip_id);
    mc_event_raise (MCEVENT_GROUP_CORE, 
                    "clipboard_file_from_ext_clip",
                    ed);