2016-09-15 9 views
6

उम्मीद है कि यह एक साधारण सी ++ प्रश्न है (भाषा-वकील नहीं)।dladdr: पॉइंटर-टू-फ़ंक्शन बनाम पॉइंटर-टू-ऑब्जेक्ट

सी ++ में जीएनयू एक्सटेंशन dladdr का उपयोग कैसे किया जाता है? आम तौर पर एक सी में निम्नलिखित लिखना होगा:

#ifndef _GNU_SOURCE 
#define _GNU_SOURCE 
#endif 
#include <dlfcn.h> 

static void where_am_i() {} 

int main() 
{ 
    Dl_info info; 
    dladdr((void*)&where_am_i, &info); 

    return 0; 
} 

हालांकि बजना का उपयोग कर एक को देखने के कलाकारों अमान्य हो सकता है कर सकते हैं:

$ clang --version 
Debian clang version 3.6.2-3 (tags/RELEASE_362/final) (based on LLVM 3.6.2) 
Target: x86_64-pc-linux-gnu 
Thread model: posix 
$ clang -Wpedantic -o foo foo.cpp -ldl 
foo.cpp:11:11: warning: cast between pointer-to-function and pointer-to-object is an extension [-Wpedantic] 
    dladdr((void*)&where_am_i, &info); 
      ^~~~~~~~~~~~~~~~~~ 
1 warning generated. 

चेतावनी मेरे लिए वैध लगता है, इसलिए वहाँ के आसपास काम करने के लिए एक रास्ता है उस ?

+1

नहीं, यह "डीएल" एपीआई की सामान्य सीमा है। यह पैकेज पॉइंटर्स को शून्य पॉइंटर्स में इस तरह से काम करता है कि सी मानक द्वारा काम करने की गारंटी नहीं है, लेकिन पॉज़िक्स को फ़ॉइंट पॉइंटर्स (और "डीएल" फ़ंक्शन पॉज़िक्स का हिस्सा हैं) रखने के लिए शून्य पॉइंटर्स की आवश्यकता होती है। –

+0

इसे लिखने के लिए बेहतर: 'शून्य * पी;/* डीएल ... */* reinterpret_cast (और where_am_i) = पी; ' –

+0

बस यह सुनिश्चित करने के लिए: हम यहां सी ++ कोड के बारे में बात कर रहे हैं, सी ++ 14 मुझे लगता है? –

उत्तर

2

फ़ंक्शन पॉइंटर को void* पर पोर्टेबल रूप से परिवर्तित करने का कोई मानक तरीका नहीं है। इस प्रकार, dladdr का पोर्टेबल उपयोग करने का कोई मानक तरीका नहीं है। सी ++ 11 से पहले, इस तरह का रूपांतरण खराब बना हुआ था (मेरे पास दस्तावेज़ उपलब्ध नहीं है, लेकिन क्लैंग द्वारा चेतावनी इसे सुझाती है)। सी ++ 11 तथापि के बाद से, रूपांतरण सशर्त समर्थित है:

[expr.reinterpret.cast]/8 (मानक प्रारूप)

एक वस्तु सूचक प्रकार या ठीक इसके विपरीत करने के लिए एक समारोह सूचक परिवर्तित सशर्त-समर्थित है। इस तरह के रूपांतरण का अर्थ कार्यान्वयन-परिभाषित है, सिवाय इसके कि यदि कोई कार्यान्वयन दोनों दिशाओं में रूपांतरणों का समर्थन करता है, तो एक प्रकार के प्रसार को दूसरे प्रकार और पीछे, संभवतः विभिन्न सीवी-योग्यता के साथ परिवर्तित करने से, मूल सूचक मूल्य प्राप्त होगा।


के बाद से आप पहले से ही है कि dladdr प्रदान करता है ग पुस्तकालय विस्तार पर निर्भर कर रहे हैं, तो आप के रूप में अच्छी आप void* को समारोह सूचक कास्ट कर सकते हैं भाषा विस्तार पर निर्भर हो सकता है। उस स्थिति में, आप संकलक से -Wpedantic विकल्प के बिना संकलन करके भाषा एक्सटेंशन का उपयोग करने के बारे में चेतावनी नहीं देना चाहेंगे - या मानक संस्करण का उपयोग करें जहां रूपांतरण कम से कम सशर्त रूप से समर्थित है। यदि रूपांतरण समर्थित नहीं है, तो dladdr नहीं है।

संबंधित मुद्दे