问题描述
我有一个C ++ dll在注入CLR后调用我的C#代码。
所以这是我的C ++(dll)代码:
I have a C++ dll which is calling my C# code after an injection with CLR.
So this is my C++ (dll) code:
#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)代码:
And this is my C# (dll) code:
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它工作正常。
它不起作用:
So it works very well for the most programs and games, but not at all. On some programs it happens nothing. The injected c++ dll try to run the c# code, but it happen nothing. My theory is that the c++ dll will create no instance of the c# dll.
But there is one option to fix that: If I change the runtime from v4.0.30319 to v2.0.50727 it works fine.
It don't work:
hr = spHost->GetRuntime(L"v4.0.30319", IID_PPV_ARGS(&spRuntimeInfo));
工作:
It work:
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它可以工作。
如何修复它或更改代码中的某些东西来运行它。
如果你们有任何想法或代码示例,我将非常感激。
我尝试过:
我试图找出为什么它不适用于所有程序,但我无法识别模式。
And now we come to my "main" problem: I have to decrease the .NET version from 4+ to 3.5 because the CLR V2 only support .NET 2 - 3.5. And this brings problems with my C# (dll) code.
So now I come to my question(s):
Why is this not working on all programs and games? (I mean with runtime v4.0.30319). With CLR RunTimeHost v2.0.50727 it works.
And how can I fix it or change something in my code to run it.
If you guys have any ideas or code examples, I would be very grateful.
What I have tried:
I tried to find out why it works not on all programs, but I can not recognize a pattern.
推荐答案
这篇关于CLR问题/它不适用于运行时v4.0.30319的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!