私の問題は次のとおりです。
次のような関数ポインタを含む構造があります。
typedef void (CALLING_COVNENTION * functionType_t) (/*...*/);
typedef struct myFuncpointerStruc_s
{
/*...*/
functionType_t funcIdentifier;
/*...*/
}myFuncpointerStruc_t;
今、まさにそのタイプの関数ポインタをそれに割り当てたいと思います。しかし悲しいことに、次のようなものではなくa をdlsym()
返していますvoid *
function_poitner_type
だから私の最初の試み:
functionscope ()
{
myFuncpointerStruc_t structIdentifier;
structIdentifier.funcIdentifier= dlsym (hAndle, "calledName");
}
警告で終了しました:
警告: ISO C では、関数ポインタと 'void *' の間の割り当てが禁止されています
わかりました、それは私を混乱させました... gccは私にそれほど厳しいことを話したことはありませんでした。しかし、ちょっとトリッキーにしましょう。標準準拠を維持するためのバックドアがおそらくあると思いました。だから私はこれを試しました:
functionscope ()
{
myFuncpointerStruc_t structIdentifier;
*(void **) &structIdentifier.funcIdentifier = dlsym (hAndle, "calledName");
}
うーん……たしかに……
警告: 型打ちされたポインターを逆参照すると、厳密なエイリアシング規則が破られます
内部で何が起こっているのかわからないので、関数をエイリアスする実数が返されるか、まったく別の何かdlsym()
が返されるため、壊れるかどうかわかりません。void *
したがって、この関数ポインターを使用すると、厳密なエイリアスルールが破られるのか、それとも破れないのかわかりません。
とにかく、私の会社では、 compilerflag を使用することは法律-fstrict-aliasing
です。したがって、これは、適合したとしても、私にとって可能な解決策ではありません。
というわけで続けてみました。
私の次のアイデアは、 のchar *
バージョンdlsym()
を memcopy に解析するにはどうすればよいかということでした。
結果:
functionscope ()
{
myFuncpointerStruc_t structIdentifier;
unsigned char *localTestPtr = ((unsigned char *) dlsym (hAndle, "calledName");
memcpy (g_interfaceSvCheck.pfnPFD_SVCHK_GET_VERSION, localTestPtr, sizeof (localTestPtr));
}
私が今得ている警告は、かなり具体的です:
警告: ISO C は、関数ポインタと void * の間で 'memcpy' の引数 1 を渡すことを禁止しています
だから私の次のアイデアは、「バイトに戻ろう」というものでした。(しかし、徐々にアイデアが不足しています...)
だから私はした:
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];
}
}
これは静かな別の警告で終わりました:
警告: ISO C では、関数ポインタからオブジェクト ポインタ型への変換が禁止されています
最後に、私の最も奇妙な試みは次のとおりです。
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
2番目のパラメーターに変換できないことです。void *
私は立ち往生していて、さらに先に進む方法がわかりません。誰かが解決策を見つけるのを手伝ってくれますか?
clangではなくgcc 4.2を使用すると、これらの警告が表示されます。
対象となる C バージョンは、-std=c99
回避することです。-std=POSIX
-std=gnu99
しかし、この gcc 警告は私には時代遅れに聞こえません。私は現在 FreeBSD に取り組んでいますが、これを解決する方法がまったくわかりません。