问题描述
我试图找到调用到从非托管C ++代码托管.NET代码的最佳执行方法。我发现我的C ++应用程序中托管.NET的信息,我能创造一个pRuntimeHost并启动它没有问题。
的
ExecuteInDefaultAppDomain,因为我似乎很有限真的要送它几个参数,并使其返回的信息的结构。最明显的替代方案是使用COM方法,但目前的C#代码是不是真的设置与方法的接口。
无论哪种方式,我想回到整数,字符串(CHAR *)S,双打等核心C ++类型。目前双方太多的代码到C ++转换为C#和使用托管C ++不是一个可接受的解决方案,因为使用此C ++代码的其他团体不希望开始使用托管代码性能方面的原因。
我们的目标是修改现有的C ++和C#代码尽可能少,但仍使用在C ++中的特定点的C#代码中的方法,而不majorly影响C ++代码的速度。
根据互联网的启动和关机顺序来承载.NET上找到的代码是:
的#includestdafx.h中
&#包括LT; metahost.h>
的#pragma评论(LIB,mscoree.lib)
INT _tmain(INT ARGC,_TCHAR *的argv [])
{
ICLRMetaHost * pMetaHost = NULL;
ICLRMetaHostPolicy * pMetaHostPolicy = NULL;
ICLRDebugging * pCLRDebugging = NULL;
HRESULT小时;
小时= CLRCreateInstance(CLSID_CLRMetaHost,IID_ICLRMetaHost,(LPVOID *)及pMetaHost);
小时= CLRCreateInstance(CLSID_CLRMetaHostPolicy,IID_ICLRMetaHostPolicy,(LPVOID *)及pMetaHostPolicy);
小时= CLRCreateInstance(CLSID_CLRDebugging,IID_ICLRDebugging,(LPVOID *)及pCLRDebugging);
DWORD dwVersion = 0;
DWORD dwImageVersion = 0;
ICLRRuntimeInfo * pRuntimeInfo;
小时= pMetaHost-> GetRuntime(Lv4.0.30319,IID_ICLRRuntimeInfo,(LPVOID *)及pRuntimeInfo);
ICLRRuntimeHost * pRuntimeHost = NULL;
小时= pRuntimeInfo-> GetInterface(CLSID_CLRRuntimeHost,IID_ICLRRuntimeHost,(LPVOID *)及pRuntimeHost);
HR = pRuntimeHost->启动();
DWORD dwRetCode = 0;
//小时= pRuntimeHost-> ExecuteInDefaultAppDomain(的argv [1],LMyNamespace.MyClass,长度消息中,L的Hello World!,&放大器; dwRetCode);
//停止CLR运行时间和关机干净。
HR = pRuntimeHost->停止();
HR = pRuntimeHost->发行();
HR = pRuntimeInfo->发行();
HR = pCLRDebugging->发行();
HR = pMetaHostPolicy->发行();
HR = pMetaHost->发行();
返回0;
}
是的,我同意约翰。你真的不希望创建运行时的一个新实例,并明确地主持它。首先,这背后的管道是没有很好的记载,并可能在未来的版本中改变。其次,C ++ / CLI旨在做的正是这一点最有效,最安全的方式。
-
编写本地C ++接口,它代表必要的.NET的funcionality。
-
设置了CLR支持使用umanaged类,它实现了原生接口的DLL。其内部实现,您可以创建和访问CLR类型,并在
gcroot<存储实例变量; T>
字段。使用CLR互操作的funcionality元帅来回托管/非托管代码之间,谷歌或冰的marshal_as
。 -
提供一个(非托管)工厂函数,它创建该组件的一个实例。这+非托管C ++接口是你的原生代码会看到API。使用DLL完全相同的方式你会使用非托管的DLL。
I'm trying to find the best performing method of calling into Managed .NET code from Unmanaged C++ code. I have found information on Hosting .NET within my C++ application and I'm able to create a pRuntimeHost and start it without a problem.
The ExecuteInDefaultAppDomain seems very limited since I really want to send it a few parameters and have it return a structure of information. The most obvious alternative is to use COM methods but the current C# code isn't really setup as interfaces with methods.
Either way I want to return integers, strings (char *)s, doubles and other core C++ types. There is too much code on both sides to convert the C++ to C# and using Managed C++ isn't an acceptable solution, since the other groups using this C++ code don't want to start using Managed code for performance reasons.
The goal is modify the existing C++ and C# code as little as possible but still use methods within the C# code at specific points within the C++ without majorly affecting the speed of the C++ code.
Based on code found on the Internet the startup and shutdown sequence to host .NET is:
#include "stdafx.h"
#include <metahost.h>
#pragma comment(lib, "mscoree.lib")
int _tmain(int argc, _TCHAR* argv[])
{
ICLRMetaHost *pMetaHost = NULL;
ICLRMetaHostPolicy *pMetaHostPolicy = NULL;
ICLRDebugging *pCLRDebugging = NULL;
HRESULT hr;
hr = CLRCreateInstance(CLSID_CLRMetaHost, IID_ICLRMetaHost, (LPVOID*)&pMetaHost);
hr = CLRCreateInstance(CLSID_CLRMetaHostPolicy, IID_ICLRMetaHostPolicy, (LPVOID*)&pMetaHostPolicy);
hr = CLRCreateInstance(CLSID_CLRDebugging, IID_ICLRDebugging, (LPVOID*)&pCLRDebugging);
DWORD dwVersion = 0;
DWORD dwImageVersion = 0;
ICLRRuntimeInfo *pRuntimeInfo;
hr = pMetaHost->GetRuntime(L"v4.0.30319", IID_ICLRRuntimeInfo, (LPVOID *)&pRuntimeInfo);
ICLRRuntimeHost * pRuntimeHost = NULL;
hr = pRuntimeInfo->GetInterface(CLSID_CLRRuntimeHost, IID_ICLRRuntimeHost, (LPVOID *)&pRuntimeHost);
hr = pRuntimeHost->Start();
DWORD dwRetCode = 0;
//hr = pRuntimeHost->ExecuteInDefaultAppDomain(argv[1], L"MyNamespace.MyClass", L"Message", L"Hello World!", &dwRetCode);
// Stop the CLR runtime and shutdown cleanly.
hr = pRuntimeHost->Stop();
hr = pRuntimeHost->Release();
hr = pRuntimeInfo->Release();
hr = pCLRDebugging->Release();
hr = pMetaHostPolicy->Release();
hr = pMetaHost->Release();
return 0;
}
Yes, I agree with John. You don't really want to create a new instance of the runtime and host it explicitely. First, the plumbing behind this is not well documented and could change in future versions. Second, C++/CLI was designed to do exactly this in most efficient and safe way.
Write native C++ interfaces which represents the required .Net funcionality.
Set up a dll with CLR support which implements the native interfaces using umanaged classes. Inside of their implementation you can create and access CLR types and store instance variables in
gcroot<T>
fields. Use the clr interop funcionality to marshal back and forth between managed/unmanaged code, google or bing formarshal_as
.Provide an (unmanaged) factory function, which creates an instance of this component. This + the unmanaged c++ interface is the API your native code will see. Use the dll exactly the same way you'd use an unmanaged dll.
这篇关于最佳调用从非托管代码托管.NET代码的方式的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!