关于这个问题找了好多地方,都只有第二种解决办法,可是我要返回一个字符串,没办法,继续找,最后还是在http://blogs.msdn.com/b/msdnforum/archive/2010/07/09/use-clr4-hosting-api-to-invoke-net-assembly-from-native-c.aspx找到了解决的办法,这里记下来备忘。

转发下范例包:http://files.cnblogs.com/files/maintell/Cpp_app_hosts_CLR_4_and_invokes_.NET_assembly_%28CppHostCLR%29.zip

第一种可以返回一个任意变量或者对象,第二种简单点,只能返回整型,具体看代码:

 //
// FUNCTION: RuntimeHostV4Demo1(PCWSTR, PCWSTR)
//
// PURPOSE: The function demonstrates using .NET Framework 4.0 Hosting
// Interfaces to host a .NET runtime, and use the ICorRuntimeHost interface
// that was provided in .NET v1.x to load a .NET assembly and invoke its
// type.
//
// If the .NET runtime specified by the pszVersion parameter cannot be
// loaded into the current process, the function prints ".NET runtime <the
// runtime version> cannot be loaded", and return.
//
// If the .NET runtime is successfully loaded, the function loads the
// assembly identified by the pszAssemblyName parameter. Next, the function
// instantiates the class (pszClassName) in the assembly, calls its
// ToString() member method, and print the result. Last, the demo invokes
// the public static function 'int GetStringLength(string str)' of the class
// and print the result too.
//
// PARAMETERS:
// * pszVersion - The desired DOTNETFX version, in the format “vX.X.XXXXX”.
// The parameter must not be NULL. It’s important to note that this
// parameter should match exactly the directory names for each version of
// the framework, under C:\Windows\Microsoft.NET\Framework[64]. The
// current possible values are "v1.0.3705", "v1.1.4322", "v2.0.50727" and
// "v4.0.30319". Also, note that the “v” prefix is mandatory.
// * pszAssemblyName - The display name of the assembly to be loaded, such
// as "CSClassLibrary". The ".DLL" file extension is not appended.
// * pszClassName - The name of the Type that defines the method to invoke.
//
// RETURN VALUE: HRESULT of the demo.
//
HRESULT RuntimeHostV4Demo1(PCWSTR pszVersion, PCWSTR pszAssemblyName,
PCWSTR pszClassName)
{
HRESULT hr; ICLRMetaHost *pMetaHost = NULL;
ICLRRuntimeInfo *pRuntimeInfo = NULL; // ICorRuntimeHost and ICLRRuntimeHost are the two CLR hosting interfaces
// supported by CLR 4.0. Here we demo the ICorRuntimeHost interface that
// was provided in .NET v1.x, and is compatible with all .NET Frameworks.
ICorRuntimeHost *pCorRuntimeHost = NULL; IUnknownPtr spAppDomainThunk = NULL;
_AppDomainPtr spDefaultAppDomain = NULL; // The .NET assembly to load.
bstr_t bstrAssemblyName(pszAssemblyName);
_AssemblyPtr spAssembly = NULL; // The .NET class to instantiate.
bstr_t bstrClassName(pszClassName);
_TypePtr spType = NULL;
variant_t vtObject;
variant_t vtEmpty; // The static method in the .NET class to invoke.
bstr_t bstrStaticMethodName(L"GetStringLength");
SAFEARRAY *psaStaticMethodArgs = NULL;
variant_t vtStringArg(L"HelloWorld");
variant_t vtLengthRet; // The instance method in the .NET class to invoke.
bstr_t bstrMethodName(L"ToString");
SAFEARRAY *psaMethodArgs = NULL;
variant_t vtStringRet; //
// Load and start the .NET runtime.
// wprintf(L"Load and start the .NET runtime %s \n", pszVersion); hr = CLRCreateInstance(CLSID_CLRMetaHost, IID_PPV_ARGS(&pMetaHost));
if (FAILED(hr))
{
wprintf(L"CLRCreateInstance failed w/hr 0x%08lx\n", hr);
goto Cleanup;
} // Get the ICLRRuntimeInfo corresponding to a particular CLR version. It
// supersedes CorBindToRuntimeEx with STARTUP_LOADER_SAFEMODE.
hr = pMetaHost->GetRuntime(pszVersion, IID_PPV_ARGS(&pRuntimeInfo));
if (FAILED(hr))
{
wprintf(L"ICLRMetaHost::GetRuntime failed w/hr 0x%08lx\n", hr);
goto Cleanup;
} // Check if the specified runtime can be loaded into the process. This
// method will take into account other runtimes that may already be
// loaded into the process and set pbLoadable to TRUE if this runtime can
// be loaded in an in-process side-by-side fashion.
BOOL fLoadable;
hr = pRuntimeInfo->IsLoadable(&fLoadable);
if (FAILED(hr))
{
wprintf(L"ICLRRuntimeInfo::IsLoadable failed w/hr 0x%08lx\n", hr);
goto Cleanup;
} if (!fLoadable)
{
wprintf(L".NET runtime %s cannot be loaded\n", pszVersion);
goto Cleanup;
} // Load the CLR into the current process and return a runtime interface
// pointer. ICorRuntimeHost and ICLRRuntimeHost are the two CLR hosting
// interfaces supported by CLR 4.0. Here we demo the ICorRuntimeHost
// interface that was provided in .NET v1.x, and is compatible with all
// .NET Frameworks.
hr = pRuntimeInfo->GetInterface(CLSID_CorRuntimeHost,
IID_PPV_ARGS(&pCorRuntimeHost));
if (FAILED(hr))
{
wprintf(L"ICLRRuntimeInfo::GetInterface failed w/hr 0x%08lx\n", hr);
goto Cleanup;
} // Start the CLR.
hr = pCorRuntimeHost->Start();
if (FAILED(hr))
{
wprintf(L"CLR failed to start w/hr 0x%08lx\n", hr);
goto Cleanup;
} //
// Load the NET assembly. Call the static method GetStringLength of the
// class CSSimpleObject. Instantiate the class CSSimpleObject and call
// its instance method ToString.
// // The following C++ code does the same thing as this C# code:
//
// Assembly assembly = AppDomain.CurrentDomain.Load(pszAssemblyName);
// object length = type.InvokeMember("GetStringLength",
// BindingFlags.InvokeMethod | BindingFlags.Static |
// BindingFlags.Public, null, null, new object[] { "HelloWorld" });
// object obj = assembly.CreateInstance("CSClassLibrary.CSSimpleObject");
// object str = type.InvokeMember("ToString",
// BindingFlags.InvokeMethod | BindingFlags.Instance |
// BindingFlags.Public, null, obj, new object[] { }); // Get a pointer to the default AppDomain in the CLR.
hr = pCorRuntimeHost->GetDefaultDomain(&spAppDomainThunk);
if (FAILED(hr))
{
wprintf(L"ICorRuntimeHost::GetDefaultDomain failed w/hr 0x%08lx\n", hr);
goto Cleanup;
} hr = spAppDomainThunk->QueryInterface(IID_PPV_ARGS(&spDefaultAppDomain));
if (FAILED(hr))
{
wprintf(L"Failed to get default AppDomain w/hr 0x%08lx\n", hr);
goto Cleanup;
} // Load the .NET assembly.
wprintf(L"Load the assembly %s\n", pszAssemblyName);
hr = spDefaultAppDomain->Load_2(bstrAssemblyName, &spAssembly);
if (FAILED(hr))
{
wprintf(L"Failed to load the assembly w/hr 0x%08lx\n", hr);
goto Cleanup;
} // Get the Type of CSSimpleObject.
hr = spAssembly->GetType_2(bstrClassName, &spType);
if (FAILED(hr))
{
wprintf(L"Failed to get the Type interface w/hr 0x%08lx\n", hr);
goto Cleanup;
} // Call the static method of the class:
// public static int GetStringLength(string str); // Create a safe array to contain the arguments of the method. The safe
// array must be created with vt = VT_VARIANT because .NET reflection
// expects an array of Object - VT_VARIANT. There is only one argument,
// so cElements = 1.
psaStaticMethodArgs = SafeArrayCreateVector(VT_VARIANT, , );
LONG index = ;
hr = SafeArrayPutElement(psaStaticMethodArgs, &index, &vtStringArg);
if (FAILED(hr))
{
wprintf(L"SafeArrayPutElement failed w/hr 0x%08lx\n", hr);
goto Cleanup;
} // Invoke the "GetStringLength" method from the Type interface.
hr = spType->InvokeMember_3(bstrStaticMethodName, static_cast<BindingFlags>(
BindingFlags_InvokeMethod | BindingFlags_Static | BindingFlags_Public),
NULL, vtEmpty, psaStaticMethodArgs, &vtLengthRet);
if (FAILED(hr))
{
wprintf(L"Failed to invoke GetStringLength w/hr 0x%08lx\n", hr);
goto Cleanup;
} // Print the call result of the static method.
wprintf(L"Call %s.%s(\"%s\") => %s\n",
static_cast<PCWSTR>(bstrClassName),
static_cast<PCWSTR>(bstrStaticMethodName),
static_cast<PCWSTR>(vtStringArg.bstrVal),
vtLengthRet.lVal); // Instantiate the class.
hr = spAssembly->CreateInstance(bstrClassName, &vtObject);
if (FAILED(hr))
{
wprintf(L"Assembly::CreateInstance failed w/hr 0x%08lx\n", hr);
goto Cleanup;
} // Call the instance method of the class.
// public string ToString(); // Create a safe array to contain the arguments of the method.
psaMethodArgs = SafeArrayCreateVector(VT_VARIANT, , ); // Invoke the "ToString" method from the Type interface.
hr = spType->InvokeMember_3(bstrMethodName, static_cast<BindingFlags>(
BindingFlags_InvokeMethod | BindingFlags_Instance | BindingFlags_Public),
NULL, vtObject, psaMethodArgs, &vtStringRet);
if (FAILED(hr))
{
wprintf(L"Failed to invoke ToString w/hr 0x%08lx\n", hr);
goto Cleanup;
} // Print the call result of the method.
wprintf(L"Call %s.%s() => %s\n",
static_cast<PCWSTR>(bstrClassName),
static_cast<PCWSTR>(bstrMethodName),
static_cast<PCWSTR>(vtStringRet.bstrVal)); Cleanup: if (pMetaHost)
{
pMetaHost->Release();
pMetaHost = NULL;
}
if (pRuntimeInfo)
{
pRuntimeInfo->Release();
pRuntimeInfo = NULL;
}
if (pCorRuntimeHost)
{
// Please note that after a call to Stop, the CLR cannot be
// reinitialized into the same process. This step is usually not
// necessary. You can leave the .NET runtime loaded in your process.
//wprintf(L"Stop the .NET runtime\n");
//pCorRuntimeHost->Stop(); pCorRuntimeHost->Release();
pCorRuntimeHost = NULL;
} if (psaStaticMethodArgs)
{
SafeArrayDestroy(psaStaticMethodArgs);
psaStaticMethodArgs = NULL;
}
if (psaMethodArgs)
{
SafeArrayDestroy(psaMethodArgs);
psaMethodArgs = NULL;
} return hr;
}

第二种比较简单:

 //
// FUNCTION: RuntimeHostV4Demo2(PCWSTR, PCWSTR)
//
// PURPOSE: The function demonstrates using .NET Framework 4.0 Hosting
// Interfaces to host a .NET runtime, and use the ICLRRuntimeHost interface
// that was provided in .NET v2.0 to load a .NET assembly and invoke its
// type. Because ICLRRuntimeHost is not compatible with .NET runtime v1.x,
// the requested runtime must not be v1.x.
//
// If the .NET runtime specified by the pszVersion parameter cannot be
// loaded into the current process, the function prints ".NET runtime <the
// runtime version> cannot be loaded", and return.
//
// If the .NET runtime is successfully loaded, the function loads the
// assembly identified by the pszAssemblyName parameter. Next, the function
// invokes the public static function 'int GetStringLength(string str)' of
// the class and print the result.
//
// PARAMETERS:
// * pszVersion - The desired DOTNETFX version, in the format “vX.X.XXXXX”.
// The parameter must not be NULL. It’s important to note that this
// parameter should match exactly the directory names for each version of
// the framework, under C:\Windows\Microsoft.NET\Framework[64]. Because
// the ICLRRuntimeHost interface does not support the .NET v1.x runtimes,
// the current possible values of the parameter are "v2.0.50727" and
// "v4.0.30319". Also, note that the “v” prefix is mandatory.
// * pszAssemblyPath - The path to the Assembly to be loaded.
// * pszClassName - The name of the Type that defines the method to invoke.
//
// RETURN VALUE: HRESULT of the demo.
//
HRESULT RuntimeHostV4Demo2(PCWSTR pszVersion, PCWSTR pszAssemblyPath,
PCWSTR pszClassName)
{
HRESULT hr; ICLRMetaHost *pMetaHost = NULL;
ICLRRuntimeInfo *pRuntimeInfo = NULL; // ICorRuntimeHost and ICLRRuntimeHost are the two CLR hosting interfaces
// supported by CLR 4.0. Here we demo the ICLRRuntimeHost interface that
// was provided in .NET v2.0 to support CLR 2.0 new features.
// ICLRRuntimeHost does not support loading the .NET v1.x runtimes.
ICLRRuntimeHost *pClrRuntimeHost = NULL; // The static method in the .NET class to invoke.
PCWSTR pszStaticMethodName = L"GetStringLength";
PCWSTR pszStringArg = L"HelloWorld";
DWORD dwLengthRet; //
// Load and start the .NET runtime.
// wprintf(L"Load and start the .NET runtime %s \n", pszVersion); hr = CLRCreateInstance(CLSID_CLRMetaHost, IID_PPV_ARGS(&pMetaHost));
if (FAILED(hr))
{
wprintf(L"CLRCreateInstance failed w/hr 0x%08lx\n", hr);
goto Cleanup;
} // Get the ICLRRuntimeInfo corresponding to a particular CLR version. It
// supersedes CorBindToRuntimeEx with STARTUP_LOADER_SAFEMODE.
hr = pMetaHost->GetRuntime(pszVersion, IID_PPV_ARGS(&pRuntimeInfo));
if (FAILED(hr))
{
wprintf(L"ICLRMetaHost::GetRuntime failed w/hr 0x%08lx\n", hr);
goto Cleanup;
} // Check if the specified runtime can be loaded into the process. This
// method will take into account other runtimes that may already be
// loaded into the process and set pbLoadable to TRUE if this runtime can
// be loaded in an in-process side-by-side fashion.
BOOL fLoadable;
hr = pRuntimeInfo->IsLoadable(&fLoadable);
if (FAILED(hr))
{
wprintf(L"ICLRRuntimeInfo::IsLoadable failed w/hr 0x%08lx\n", hr);
goto Cleanup;
} if (!fLoadable)
{
wprintf(L".NET runtime %s cannot be loaded\n", pszVersion);
goto Cleanup;
} // Load the CLR into the current process and return a runtime interface
// pointer. ICorRuntimeHost and ICLRRuntimeHost are the two CLR hosting
// interfaces supported by CLR 4.0. Here we demo the ICLRRuntimeHost
// interface that was provided in .NET v2.0 to support CLR 2.0 new
// features. ICLRRuntimeHost does not support loading the .NET v1.x
// runtimes.
hr = pRuntimeInfo->GetInterface(CLSID_CLRRuntimeHost,
IID_PPV_ARGS(&pClrRuntimeHost));
if (FAILED(hr))
{
wprintf(L"ICLRRuntimeInfo::GetInterface failed w/hr 0x%08lx\n", hr);
goto Cleanup;
} // Start the CLR.
hr = pClrRuntimeHost->Start();
if (FAILED(hr))
{
wprintf(L"CLR failed to start w/hr 0x%08lx\n", hr);
goto Cleanup;
} //
// Load the NET assembly and call the static method GetStringLength of
// the type CSSimpleObject in the assembly.
// wprintf(L"Load the assembly %s\n", pszAssemblyPath); // The invoked method of ExecuteInDefaultAppDomain must have the
// following signature: static int pwzMethodName (String pwzArgument)
// where pwzMethodName represents the name of the invoked method, and
// pwzArgument represents the string value passed as a parameter to that
// method. If the HRESULT return value of ExecuteInDefaultAppDomain is
// set to S_OK, pReturnValue is set to the integer value returned by the
// invoked method. Otherwise, pReturnValue is not set.
hr = pClrRuntimeHost->ExecuteInDefaultAppDomain(pszAssemblyPath,
pszClassName, pszStaticMethodName, pszStringArg, &dwLengthRet);
if (FAILED(hr))
{
wprintf(L"Failed to call GetStringLength w/hr 0x%08lx\n", hr);
goto Cleanup;
} // Print the call result of the static method.
wprintf(L"Call %s.%s(\"%s\") => %d\n", pszClassName, pszStaticMethodName,
pszStringArg, dwLengthRet); Cleanup: if (pMetaHost)
{
pMetaHost->Release();
pMetaHost = NULL;
}
if (pRuntimeInfo)
{
pRuntimeInfo->Release();
pRuntimeInfo = NULL;
}
if (pClrRuntimeHost)
{
// Please note that after a call to Stop, the CLR cannot be
// reinitialized into the same process. This step is usually not
// necessary. You can leave the .NET runtime loaded in your process.
//wprintf(L"Stop the .NET runtime\n");
//pClrRuntimeHost->Stop(); pClrRuntimeHost->Release();
pClrRuntimeHost = NULL;
} return hr;
}

最新文章

  1. Strus2学习:基础(一)
  2. C#中使用Sql对Excel条件查询
  3. 部署移动BI必须要考虑的五大因素
  4. Java基础 —— CSS
  5. PHP中include和require绝对路径、相对路径问题
  6. 正式学习react(二)
  7. 腾讯课堂-草图大师 Sketchup 初级到精通视频讲座
  8. 修改合同号的bapi
  9. javaMail邮件发送功能(多收件人,多抄送人,多密送人,多附件)
  10. 使用 ng build 构建后资源地址引用错误的问题
  11. python练习题3:N的多次方
  12. laravel 关联中的预加载
  13. python基础(3)-pycharm安装&amp;for循环&amp;format字符串&amp;list列表&amp;set集合使用
  14. bzoj1294
  15. DOS 格式化日期时间输出
  16. 第十一章&#160;串 (b2)蛮力匹配
  17. asp.net给文件分配自己主动编号,如【20140710-1】
  18. 像网页开发一样调试ios程序
  19. PHP接入支付宝支付
  20. 使用 Build Pipeline View 插件图表展示Jenkins job依赖关系

热门文章

  1. 编写自定义cmake配置文件FindXXX.cmake或者xxx-config.cmake | cmake with user defined entry
  2. Java Import的使用
  3. 最全 HTTP 安全响应头设置指南
  4. 跨平台c开发库tbox:内存库使用详解
  5. DNS服务正向解析实验
  6. MySQL必知必会(创建计算字段(field))
  7. MySQL必知必会(Select, Order by子句)
  8. IDEA插件开发(一)一个简单的表单demo
  9. MongoDB第一天(MongoDB的简介和安装)
  10. idea结合maven小项目