gpt4 book ai didi

c - 如何将 dlsym() 的返回值分配给函数类型?

转载 作者:太空宇宙 更新时间:2023-11-03 23:29:33 25 4
gpt4 key购买 nike

我的问题如下:

我有一个包含这样的函数指针的结构:

typedef void (CALLING_COVNENTION * functionType_t) (/*...*/);

typedef struct myFuncpointerStruc_s
{
/*...*/
functionType_t funcIdentifier;
/*...*/
}myFuncpointerStruc_t;

现在我想为它分配一个完全相同类型的函数指针。但遗憾的是 dlsym() 返回的是 void * 而不是 function_poitner_type

所以我的第一次尝试:

functionscope ()
{
myFuncpointerStruc_t structIdentifier;

structIdentifier.funcIdentifier= dlsym (hAndle, "calledName");
}

结束于警告:

WARNING: ISO C forbids assignment between function pointer and 'void *'

好吧,这让我很困惑……gcc 从来没有对我说那么严厉的话。但是好吧,让我们变得棘手吧,我认为可能会有任何后门来保持它的标准一致性。所以我尝试了这个:

functionscope ()
{
myFuncpointerStruc_t structIdentifier;

*(void **) &structIdentifier.funcIdentifier = dlsym (hAndle, "calledName");
}

嗯....显然...

warning: dereferencing type-punned pointer will break strict aliasing rules

因为我不知道 dlsym() 内部发生了什么,所以我不知道我会中断,因为我返回了一个真正的 void * 别名我的函数,或者完全不同的东西,我可以吗?

所以我不知道,现在使用这个函数指针是否会违反严格的别名规则?

但无论如何:对于我的公司来说,使用编译器标志 -fstrict-aliasing 是合法的。所以这对我来说也不是一个可能的解决方案,即使它符合要求。

所以我继续尝试。

我的下一个想法是:如何将 dlsym()char * 版本解析为 memcopy?

结果:

functionscope ()
{
myFuncpointerStruc_t structIdentifier;

unsigned char *localTestPtr = ((unsigned char *) dlsym (hAndle, "calledName");

memcpy (g_interfaceSvCheck.pfnPFD_SVCHK_GET_VERSION, localTestPtr, sizeof (localTestPtr));
}

我现在收到的警告再次非常具体:

warning: ISO C forbids passing argument 1 of ´memcpy´ between function pointer and ´void *´

所以我的下一个想法是“让我们回到字节”,也许在那里我会找到一个可以继续工作的方法。(但慢慢地我的想法用完了......)

所以我做了:

functionscope ()
{
size_t testIndex;
myFuncpointerStruc_t structIdentifier;
unsigned char *localTestPtr = ((unsigned char *) dlsym (hAndle, "calledName");

for (testIndex = 0; testIndex < sizeof (localTestPtr); testIndex++)
{
((unsigned char *)(structIdentifier.funcIdentifier))[testIndex] = ((unsigned char *)&localTestPtr)[testIndex];
}

}

这以一个安静的不同警告结束:

WARNING: ISO C forbids conversion of function pointer to object pointer type

所以最后我最疯狂的尝试是:

functionscope ()
{
size_t testIndex;
myFuncpointerStruc_t structIdentifier;
unsigned char *localTestPtr = ((unsigned char *) dlsym (hAndle, "calledName");
unsigned char * FakeFunctionPointer;

FakeFunctionPointer =
(((unsigned char *)structIdentifier) + offsetof (myFuncpointerStruc_t , funcIdentifier));

for (testIndex = 0; testIndex < sizeof (localTestPtr); testIndex++)
{
FakeFunctionPointer[testIndex] = ((unsigned char *)&localTestPtr)[testIndex];
}
}

问题是,offsetoff 的第二个参数无法转换为 void *,因为它是一个函数指针。

我被困住了,不知道如何更进一步,有人能帮我找到解决方案吗?

我只是通过使用 gcc 4.2 而不是 clang 收到这些警告。

objective-c 版本是 -std=c99 要避免的是 -std=POSIX-std=gnu99

但是这个 gcc 警告对我来说并没有过时。我目前在 FreeBSD 上工作,我真的不知道如何解决这个问题。

最佳答案

这有点棘手:

#define CALLING_CONVENTION 

typedef void (CALLING_CONVENTION * functionType_t) (/*...*/);
typedef struct myFuncpointerStruc_s
{
/*...*/
functionType_t funcIdentifier;
/*...*/
} myFuncpointerStruc_t;

int main()
{
myFuncpointerStruc_t structIdentifier = {0};

{
functionType_t * pfuncIdentifier = &structIdentifier.funcIdentifier;

*(void **) (pfuncIdentifier) = dlsym(handle, "calledName");
}

...
}

上述解决方案只是编译器的技巧。从 -O1 开始不再工作......:-(


既然确实无解,唯一的办法就是让编译器冷静下来。 GNU 人员对此表现出了洞察力并发明了:__attribute__ ((__may_alias__))

这里我们可以这样使用:

#define CALLING_CONVENTION 

typedef void * __attribute__ ((__may_alias__)) pvoid_may_alias_t;

typedef void (CALLING_CONVENTION * functionType_t) (/*...*/);
typedef struct myFuncpointerStruc_s
{
/*...*/
functionType_t funcIdentifier;
/*...*/
} myFuncpointerStruc_t;

int main()
{
myFuncpointerStruc_t structIdentifier = {0};

*(pvoid_may_alias_t *) (&structIdentifier.funcIdentifier) = dlsym(handle, "calledName");
}

...
}

顺便说一句:ldsym() 从何而来?我只知道dlsym()

关于c - 如何将 dlsym() 的返回值分配给函数类型?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/19116487/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com