У меня есть C ++ dll, которая вызывает мой код C # после внедрения с помощью CLR.
Так что это мой код C ++ (dll):
#include "stdafx.h"
#include <iostream>
#include <metahost.h>
#include <atlbase.h>
#include <atlcom.h>
#pragma comment(lib, "mscoree.lib")
#define IfFailRet(expr) { hr = (expr); if(FAILED(hr)) return (hr); }
#define IfNullFail(expr) { if (!expr) return (E_FAIL); }
extern "C" int __declspec(dllexport) CALLBACK CallClrMethod(
const WCHAR *AssemblyName,
const WCHAR *TypeName,
const WCHAR *MethodName,
const WCHAR *args,
LPDWORD pdwResult
)
{
int hr = S_OK;
CComPtr<ICLRMetaHost> spHost;
hr = CLRCreateInstance(CLSID_CLRMetaHost, IID_PPV_ARGS(&spHost));
CComPtr<ICLRRuntimeInfo> spRuntimeInfo;
CComPtr<IEnumUnknown> pRunTimes;
IfFailRet(spHost->EnumerateInstalledRuntimes(&pRunTimes));
CComPtr<IUnknown> pUnkRuntime;
while (S_OK == pRunTimes->Next(1, &pUnkRuntime, 0))
{
CComQIPtr<ICLRRuntimeInfo> pp(pUnkRuntime);
if (pUnkRuntime != nullptr)
{
spRuntimeInfo = pp;
break;
}
}
IfNullFail(spRuntimeInfo);
BOOL bStarted;
DWORD dwStartupFlags;
hr = spRuntimeInfo->IsStarted(&bStarted, &dwStartupFlags);
if (hr != S_OK) // sometimes 0x80004001 not implemented
{
spRuntimeInfo = nullptr; //v4.0.30319 //v2.0.50727
hr = spHost->GetRuntime(L"v2.0.50727", IID_PPV_ARGS(&spRuntimeInfo));
bStarted = false;
}
CComPtr<ICLRRuntimeHost> spRuntimeHost;
IfFailRet(spRuntimeInfo->GetInterface(CLSID_CLRRuntimeHost, IID_PPV_ARGS(&spRuntimeHost)));
if (!bStarted)
{
hr = spRuntimeHost->Start();
}
hr = spRuntimeHost->ExecuteInDefaultAppDomain(
AssemblyName,
TypeName,
MethodName,
args,
pdwResult);
return hr;
}
int _tmain(int argc, _TCHAR* argv[])
{
DWORD dwResult;
HRESULT hr = CallClrMethod(
L"D:\\Dev\\CSharpDll\\CSharpDll\\bin\\x64\\Debug\\CSharpDll.dll",
L"CSharpDll.MainClass",
L"EntryPoint",
L"Im successfully called from a C++ dll",
&dwResult);
return 0;
}
BOOL APIENTRY DllMain(HMODULE hModule,
DWORD ul_reason_for_call,
LPVOID lpReserved
)
{
switch (ul_reason_for_call)
{
case DLL_PROCESS_ATTACH:
CreateThread(NULL, NULL, (LPTHREAD_START_ROUTINE)_tmain, hModule, NULL, NULL);
break;
case DLL_THREAD_ATTACH:
break;
case DLL_THREAD_DETACH:
break;
case DLL_PROCESS_DETACH:
break;
}
return TRUE;
}
И это мой C #(DLL) код:
using System.Windows.Forms;
namespace CSharpDll
{
public class MainClass
{
public static int EntryPoint(string MessageFromCppDll)
{
MessageBox.Show(MessageFromCppDll);
Form form = new MainForm();
form.ShowDialog();
return 0;
}
}
}
Так что он работает очень хорошо для большинства программ и игр, но не на всех.На некоторых программах ничего не происходит.Внедренный c ++ dll пытается запустить код c #, но ничего не происходит.Моя теория состоит в том, что c ++ dll не создаст экземпляр c # dll.
Но есть один вариант, чтобы это исправить: если я изменю среду выполнения с v4.0.30319 на v2.0.50727, она будет работать нормально.
Это не работает:
hr = spHost->GetRuntime(L"v4.0.30319", IID_PPV_ARGS(&spRuntimeInfo));
Это работает:
hr = spHost->GetRuntime(L"v2.0.50727", IID_PPV_ARGS(&spRuntimeInfo));
И теперь мы подошли к моей "главной" проблеме: мне нужно уменьшить.Версия NET от 4+ до 3.5, потому что CLR V2 поддерживает только .NET 2 - 3.5.И это вызывает проблемы с моим C # (dll) кодом.
Итак, теперь я перехожу к моему вопросу (ам):
Почему это работает не на всех программах иигры?(Я имею в виду время выполнения v4.0.30319).С CLR RunTimeHost v2.0.50727 это работает.
И как я могу это исправить или изменить что-то в моем коде, чтобы запустить его.
Еслиребята, у вас есть идеи или примеры кода, я был бы очень признателен.