2011-07-28 13 views
18

Chcę napisać profiler CLR, aby podłączyć naszą funkcję aplikacji z GetILFunctionBody/SetILFunctionBody.Profiler CLR: problem przy użyciu DefineAssemblyRef

Chcę użyć DefineAssemblyRef do importowania naszego C# dll (do użycia w kodzie IL) w tym kodzie DefineAssemblyRef zawsze zwraca True? Czy moja biblioteka dll musi być podpisana? Czy musi być zainstalowany w pamięci podręcznej Global Assembly Cache (GAC)?

 HRESULT CProfilerCallback::JITCompilationStarted 
     (
     UINT functionId, 
     BOOL fIsSafeToBlock 
     ) 
    { 
     ClassID classID; 
     ModuleID moduleID; 
     mdToken token; 
     wchar_t wszClass[512]; 
     wchar_t wszMethod[512]; 
     HRESULT result = S_OK; 
     ClassID classId = 0; 
     ModuleID moduleId = 0; 
     mdToken tkMethod = 0; 

     // Get the moduleID and tkMethod  
     m_pICorProfilerInfo->GetFunctionInfo(functionId, &classId, &moduleId, &tkMethod); 

     if(!GetMethodNameFromFunctionId(functionId,wszClass,wszMethod)) 
     {return S_FALSE;} 


     if(wcscmp(wszMethod,L"FunctionName") == 0) 
     { 
      // Get the metadata import 
      IMetaDataImport* pMetaDataImport = NULL; 
      DebugBreak(); 
      result = m_pICorProfilerInfo->GetModuleMetaData 
       (
       moduleId, 
       ofRead, 
       IID_IMetaDataImport, 
       (IUnknown**)&pMetaDataImport 
       ); 


      if (FAILED(result)) 
      { return S_FALSE;} 
     // 
     // Metadata modification 
     // 
     IMetaDataEmit* pMetaDataEmit = NULL;  
     IMetaDataAssemblyEmit* pMetaDataAssemblyEmit = NULL; 
     mdAssemblyRef tkLoggerLib; 
     HRESULT res; 
     res = m_pICorProfilerInfo->GetModuleMetaData 
      (
      moduleId,   /// The ID of the module to which the interface instance will be mapped 
      ofRead | ofWrite, 
      IID_IMetaDataEmit, 
      (IUnknown**)&pMetaDataEmit 
      ); 

     if (FAILED(res)) {DebugBreak(); return S_FALSE;} /// DebugBreak for debug 

     res = pMetaDataEmit->QueryInterface 
      (
      IID_IMetaDataAssemblyEmit, 
      (void**)&pMetaDataAssemblyEmit 
      ); 

     if (FAILED(res)) { return S_FALSE;} 

     // Get the token for the Logger class and its Log method 
     mdTypeDef tkLogger = 0; 
     mdMethodDef tkLog = 0; 

     // Create a token for the Log.dll assembly 
     ASSEMBLYMETADATA amd; 
     ZeroMemory(&amd, sizeof(amd)); 
     amd.usMajorVersion = 0; 
     amd.usMinorVersion = 0; 
     amd.usBuildNumber = 0; 
     amd.usRevisionNumber = 0; 

     res= pMetaDataAssemblyEmit->DefineAssemblyRef 
      (
      NULL, 0, // No public key token 
      L"Dllname", ///dll name 
      &amd, NULL, 0, 0, 
      &tkLoggerLib 
      ); 

     if (FAILED(res)) {return S_FALSE; } 

       ...... 
+1

Od lat nie zajmowałem się programistami .NET, więc mogłem być tutaj bez bazy, ale dlaczego oczekiwałeś, że DefineAssemblyRef się nie powiedzie? Po prostu deklarujesz referencję - faktyczny montaż nie zostanie rozwiązany, dopóki referencja nie zostanie użyta. Twoje złożenie nie musi być podpisane lub w GAC, ale zespół wywołujący musi być w stanie go znaleźć, więc jeśli nie znajduje się w GAC, musi znajdować się w katalogu, który znajduje się na ścieżce wyszukiwania, IIRC. –

+0

Dla potomności [ten link] (http://www.dupuis.me/node/18) został opublikowany jako odpowiedź, która wydaje się, że może zostać usunięta. Opis w linku wydaje się być bardzo trafny w odniesieniu do tego pytania, chociaż nie wiem, czy wiem. – Ben

Odpowiedz

1

Zgodnie z tym blogu MSDN http://blogs.msdn.com/b/davbr/archive/2006/02/27/540280.aspx:

IMetaDataAssemblyEmit :: DefineAssemblyRef() daje mdAssemblyRef do swojego zespołu. Trochę pracy jest konieczne, aby to naprawić. Niezawodny sposób na odniesienie się do twojego zespołu to podpisanie twojego zespołu, dodanie go do GAC i użycie klucza publicznego, który "gacutil/l" wydrukuje dla ciebie

Możesz również znaleźć użyteczny ten projekt - dynamiczny hook CLR wstrzyknięcie http://www.dupuis.me/node/18 tego rodzaju pokazuje, co próbujesz zrobić.

Powiązane problemy