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; }
......
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. –
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