2012-07-18 7 views
21

विजुअल स्टूडियो 2012 डीबगर के लिए सी ++ में कस्टम देशी विज़ुअलाइज़र डीएलएल लिखने के लिए क्या आवश्यक है? मैं एक ऐसा मूल्य प्रदर्शित करना चाहता हूं जिसे केवल कक्षा/संरचना से मांग पर ही गणना की जा सके, इसलिए देशी विज़ुअलाइज़र डीएलएल की आवश्यकता होती है। विजुअल स्टूडियो 2012 नेटविस नामक देशी विज़ुअलाइज़र को लागू करने के लिए एक नई विधि का उपयोग करता है। इस समय तक, नाटविस पर विशेष रूप से नाटविस का उपयोग करने पर विज़ुअलाइज़र डीएलएल को कॉल करने के लिए बहुत कम सही जानकारी है। डीएलएल कक्षा/संरचना सदस्य मूल्यों के आधार पर एक प्रदर्शन स्ट्रिंग की गणना करेगा।विजुअल स्टूडियो 2012 डीबगर के लिए कस्टम देशी विज़ुअलाइज़र डीएलएल कैसे लिखें?

+0

http://code.msdn.microsoft.com/windowsdesktop/Writing-type-visualizers-2eae77a2 –

+0

कि एक महान natvis पद है, जो मैं भी नीचे उल्लेख है, लेकिन यह लेखन के बारे में एक शब्द भी नहीं है एक कस्टम देशी विजुअलाइज़र डीएलएल। मैं उदार हो जाऊंगा और कहूंगा कि माइक्रोसॉफ्ट के पूरे विषय को कवर करने के लिए गेम में बहुत जल्दी है। – BSalita

उत्तर

38

यहां सी ++ कोड है जिसमें एडइन डीएलएल शामिल है। मैंने NatvisAddIn.cpp फ़ाइल नामित की है और प्रोजेक्ट ने NatvisAddIn.dll बनाया है।

#include "stdafx.h" 
#include <iostream> 
#include <windows.h> 

#define ADDIN_API __declspec(dllexport) 

typedef struct tagDEBUGHELPER 
{ 
    DWORD dwVersion; 
    HRESULT (WINAPI *ReadDebuggeeMemory)(struct tagDEBUGHELPER *pThis, DWORD dwAddr, DWORD nWant, VOID* pWhere, DWORD *nGot); 
    // from here only when dwVersion >= 0x20000 
    DWORDLONG (WINAPI *GetRealAddress)(struct tagDEBUGHELPER *pThis); 
    HRESULT (WINAPI *ReadDebuggeeMemoryEx)(struct tagDEBUGHELPER *pThis, DWORDLONG qwAddr, DWORD nWant, VOID* pWhere, DWORD *nGot); 
    int (WINAPI *GetProcessorType)(struct tagDEBUGHELPER *pThis); 
} DEBUGHELPER; 

typedef HRESULT (WINAPI *CUSTOMVIEWER)(DWORD dwAddress, DEBUGHELPER *pHelper, int nBase, BOOL bUniStrings, char *pResult, size_t max, DWORD reserved); 

extern "C" ADDIN_API HRESULT MyClassFormatter(DWORD dwAddress, DEBUGHELPER *pHelper, int nBase, BOOL bUniStrings, char *pResult, size_t max, DWORD reserved); 
extern "C" ADDIN_API HRESULT MyStructFormatter(DWORD dwAddress, DEBUGHELPER *pHelper, int nBase, BOOL bUniStrings, char *pResult, size_t max, DWORD reserved); 

class MyClass 
{ 
public: 
    int publicInt; 
}; 

struct MyStruct { int i; }; 

ADDIN_API HRESULT MyClassFormatter(DWORD dwAddress, DEBUGHELPER *pHelper, int nBase, BOOL bUniStrings, char *pResult, size_t max, DWORD reserved) 
{ 
    MyClass c; 
    DWORD nGot; 
    pHelper->ReadDebuggeeMemory(pHelper,dwAddress,sizeof(MyClass),&c,&nGot); 
    sprintf_s(pResult,max,"Dll MyClass: max=%d nGot=%d MyClass=%x publicInt=%d",max,nGot,dwAddress,c.publicInt); 
    return S_OK; 
} 

ADDIN_API HRESULT MyStructFormatter(DWORD dwAddress, DEBUGHELPER *pHelper, int nBase, BOOL bUniStrings, char *pResult, size_t max, DWORD reserved) 
{ 
    MyStruct s; 
    DWORD nGot; 
    pHelper->ReadDebuggeeMemory(pHelper,dwAddress,sizeof(MyStruct),&s,&nGot); 
    sprintf_s(pResult,max,"Dll MyStruct: max=%d nGot=%d MyStruct=%x i=%d",max,nGot,dwAddress,s.i); 
    return S_OK; 
} 

यहाँ .natvis फ़ाइल जो Visual Studio 2012 डिबगर मूल्य प्रदर्शित करने के लिए उपयोग करता है। इसे एक .natvis फ़ाइल में रखें। मैंने इसे NatvisAddIn.natvis नाम दिया। फ़ाइल NatvisAddIn.dll को कॉल करने के लिए वीएस 2012 डीबगर निर्देश देती है। डीएलएल में दो विज़ुअलाइज़र विधि कॉल शामिल हैं; MyClass प्रारूप बनाने के लिए MyClass और MyStructFormatter प्रारूपित करने के लिए MyClassFormatter। डीबगर निर्दिष्ट प्रकार (MyClass, MyStruct) के प्रत्येक उदाहरण के लिए ऑटो, वॉच या टूलटिप डिस्प्ले में विधि का स्वरूपित मान दिखाएगा।

<?xml version="1.0" encoding="utf-8"?> 
    <AutoVisualizer xmlns="http://schemas.microsoft.com/vstudio/debugger/natvis/2010"> 
    <Type Name="MyClass"> 
     <DisplayString LegacyAddin="NatvisAddIn.dll" Export="MyClassFormatter"></DisplayString> 
    </Type> 
    <Type Name="MyStruct"> 
     <DisplayString LegacyAddin="NatvisAddIn.dll" Export="MyStructFormatter"></DisplayString> 
    </Type> 
</AutoVisualizer> 

प्लेस दोनों संकलित NatvisAddIn.dll फ़ाइल और निम्नलिखित तीन स्थानों में से एक में NatvisAddIn.natvis फ़ाइलें:

%VSINSTALLDIR%\Common7\Packages\Debugger\Visualizers (requires admin access) 

%USERPROFILE%\My Documents\Visual Studio 2012\Visualizers\ 

VS extension folders 

तुम्हें यकीन निम्न रजिस्ट्री कुंजी मौजूद है और मूल्य बनाने के लिए की आवश्यकता होगी 1:

[HKEY_CURRENT_USER \ Software \ Microsoft \ VisualStudio \ 11.0_Config \ डीबगर]

"EnableNatvisDiagnostics" = DWORD: 00000001

सब कुछ ठीक है, तो आप natvis देखेंगे संदेशों दृश्य स्टूडियो के डिबगर आउटपुट विंडो में दिखाई देते हैं। संदेश दिखाएंगे कि क्या नेटविस .natvis फ़ाइलों को पार्स करने में सक्षम था। प्रत्येक .natvis फ़ाइल को पार्स करने के परिणाम आउटपुट विंडो में दिखाए जाते हैं। यदि कुछ गलत है, तो "डंपबिन/निर्यात" कमांड को दोबारा जांचने के लिए उपयोग करें कि DLL विधियों के नाम बिल्कुल .navis फ़ाइल के प्रकार = से मेल खाते हैं। यह भी सुनिश्चित करें कि वर्तमान .dll और .natvis फ़ाइलों को उचित निर्देशिका में कॉपी किया गया है।

Natvis: Parsing natvis xml file: C:\Program Files (x86)\Microsoft Visual Studio 11.0\Common7\Packages\Debugger\Visualizers\atlmfc.natvis. 
Natvis: Done parsing natvis xml file: C:\Program Files (x86)\Microsoft Visual Studio 11.0\Common7\Packages\Debugger\Visualizers\atlmfc.natvis. 
Natvis: Parsing natvis xml file: C:\Program Files (x86)\Microsoft Visual Studio 11.0\Common7\Packages\Debugger\Visualizers\concurrency.natvis. 
Natvis: Done parsing natvis xml file: C:\Program Files (x86)\Microsoft Visual Studio 11.0\Common7\Packages\Debugger\Visualizers\concurrency.natvis. 
Natvis: Parsing natvis xml file: C:\Program Files (x86)\Microsoft Visual Studio 11.0\Common7\Packages\Debugger\Visualizers\NatvisAddIn.natvis. 
Natvis: Done parsing natvis xml file: C:\Program Files (x86)\Microsoft Visual Studio 11.0\Common7\Packages\Debugger\Visualizers\NatvisAddIn.natvis. 
Natvis: Parsing natvis xml file: C:\Program Files (x86)\Microsoft Visual Studio 11.0\Common7\Packages\Debugger\Visualizers\stl.natvis. 
Natvis: Done parsing natvis xml file: C:\Program Files (x86)\Microsoft Visual Studio 11.0\Common7\Packages\Debugger\Visualizers\stl.natvis. 
Natvis: Parsing natvis xml file: C:\Program Files (x86)\Microsoft Visual Studio 11.0\Common7\Packages\Debugger\Visualizers\windows.natvis. 
Natvis: Done parsing natvis xml file: C:\Program Files (x86)\Microsoft Visual Studio 11.0\Common7\Packages\Debugger\Visualizers\windows.natvis. 
Natvis: Parsing natvis xml file: C:\Program Files (x86)\Microsoft Visual Studio 11.0\Common7\Packages\Debugger\Visualizers\winrt.natvis. 
Natvis: Done parsing natvis xml file: C:\Program Files (x86)\Microsoft Visual Studio 11.0\Common7\Packages\Debugger\Visualizers\winrt.natvis. 

टेस्ट कार्यक्रम:

#include "stdafx.h" 
#include <iostream> 

class MyClass 
{ 
public: 
    int publicInt; 
}; 

struct MyStruct { int i; }; 

int _tmain(int argc, _TCHAR* argv[]) 
{ 
    struct MyStruct s = {1234}; 
    std::cout << s.i << std::endl; 
    MyClass *c = new MyClass; 
    c->publicInt = 1234; 
    std::cout << c->publicInt << std::endl; 
    return 0; 
} 

सूचना संसाधन:

\ Xml \ स्कीमा \ natvis।XSD

http://code.msdn.microsoft.com/windowsdesktop/Writing-type-visualizers-2eae77a2

http://blogs.msdn.com/b/mgoldin/archive/2012/06/06/visual-studio-2012-and-debugger-natvis-files-what-can-i-do-with-them.aspx

http://blogs.msdn.com/b/vcblog/archive/2012/07/12/10329460.aspx

+0

यह क्यों कम हो गया? –

+1

पूछने के लिए धन्यवाद। संभवतः कुछ डाउनवॉट्स थे क्योंकि मैंने सभी स्टब्स में भर नहीं लिया था। मैं रीयलटाइम में जोड़ रहा था। मैंने सीखा कि यदि संभव हो, तो मुझे प्रारंभिक पोस्ट पर पोस्ट को पूरा करना चाहिए। पोस्ट अब पूरा हो गया है इसलिए – BSalita

+1

पोस्ट करने के लिए पहले बहुत सारे उपरोक्त होना चाहिए, लेकिन मुझे नहीं लगता कि यह 64-बिट ऐप्स के लिए काम करेगा। (उदाहरण के लिए पते के लिए DWORD का उपयोग किया जाता है, और अन्य चीजें)। साथ ही कोई एक प्लगइन बनाने के लिए कैसे जाएगा जो किसी भी तरह से दूसरी तरफ 32-बिट/64-बिट कोड से संबंधित है? – malkia

1

64 बिट संस्करण डिबगिंग के लिए, निम्नलिखित लाइनों इस्तेमाल किया जाना चाहिए:

auto realAddress = pHelper->GetRealAddress(pHelper); 
pHelper->ReadDebuggeeMemoryEx(pHelper, realAddress, sizeof(MyClass), &c, &nGot); 

पिछले उदाहरण के लिए, 64 बिट संस्करण की तरह लग सकता है यह:

#include "stdafx.h" 
#include <iostream> 
#include <windows.h> 

#define ADDIN_API __declspec(dllexport) 

typedef struct tagDEBUGHELPER 
{ 
    DWORD dwVersion; 
    HRESULT (WINAPI *ReadDebuggeeMemory)(struct tagDEBUGHELPER *pThis, DWORD dwAddr, DWORD nWant, VOID* pWhere, DWORD *nGot); 
    // from here only when dwVersion >= 0x20000 
    DWORDLONG (WINAPI *GetRealAddress)(struct tagDEBUGHELPER *pThis); 
    HRESULT (WINAPI *ReadDebuggeeMemoryEx)(struct tagDEBUGHELPER *pThis, DWORDLONG qwAddr, DWORD nWant, VOID* pWhere, DWORD *nGot); 
    int (WINAPI *GetProcessorType)(struct tagDEBUGHELPER *pThis); 
} DEBUGHELPER; 

typedef HRESULT (WINAPI *CUSTOMVIEWER)(DWORD dwAddress, DEBUGHELPER *pHelper, int nBase, BOOL bUniStrings, char *pResult, size_t max, DWORD reserved); 

extern "C" ADDIN_API HRESULT MyClassFormatter(DWORD dwAddress, DEBUGHELPER *pHelper, int nBase, BOOL bUniStrings, char *pResult, size_t max, DWORD reserved); 

class MyClass 
{ 
public: 
    int publicInt; 
}; 

ADDIN_API HRESULT MyClassFormatter(DWORD dwAddress, DEBUGHELPER *pHelper, int nBase, BOOL bUniStrings, char *pResult, size_t max, DWORD reserved) 
{ 
    MyClass c; 
    DWORD nGot; 
    auto realAddress = pHelper->GetRealAddress(pHelper); 
    pHelper->ReadDebuggeeMemoryEx(pHelper, realAddress, sizeof(MyClass), &c, &nGot); 
    sprintf_s(pResult,max,"Dll MyClass: max=%d nGot=%d MyClass=%llx publicInt=%d",max, nGot, realAddress, c.publicInt); 
    return S_OK; 
} 
संबंधित मुद्दे