关于这个问题找了好多地方,都只有第二种解决办法,可是我要返回一个字符串,没办法,继续找,最后还是在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;
}

native C++ 动态调用.NET DLL的更多相关文章

  1. C#实现动态调用Windows DLL

    调用方法: object obj = WinDllInvoke("Kernel32.dll", "Beep", , }, typeof(void)); 函数代码 ...

  2. C# 中静态调用C++dll 和C# 中动态调用C++dll

    在最近的项目中,牵涉到项目源代码保密问题,由于代码是C#写的,容易被反编译,因此决定抽取核心算法部分使用C++编写,C++到目前为止好像还不能被很好的反编译,当然如果你是反汇编高手的话,也许还是有可能 ...

  3. 关于C#动态调用VC Dll的方法(转)

    http://blog.csdn.net/null1/article/details/3953155

  4. Delphi DLL的创建、静态及动态调用

    转载:http://blog.csdn.net/welcome000yy/article/details/7905463 结合这篇博客:http://www.cnblogs.com/xumenger/ ...

  5. C#程序实现动态调用DLL的研究(转)

    摘 要:在<csdn开发高手>2004年第03期中的<化功大法——将DLL嵌入EXE>一文,介绍了如何把一个动态链接库作为一个资源嵌入到可执行文件,在可执行文件运行时,自动从资 ...

  6. C#程序实现动态调用DLL的研究[转]

    摘   要: 在< csdn 开发高手> 2004 年第 03 期中的<化功大法——将 DLL 嵌入 EXE >一文,介绍了如何把一个动态链接库作为一个资源嵌入到可执行文件,在 ...

  7. C#程序实现动态调用DLL的研究

    摘 要:在<csdn开发高手>2004年第03期中的<化功大法——将DLL嵌入EXE>一文,介绍了如何把一个动态链接库作为一个资源嵌入到可执行文件,在可执行文件运行时,自动从资 ...

  8. [转]Delphi DLL的创建、静态 以及动态调用

    第一章  DLL简单介绍 由于在目前的学习工作中,需要用到DLL文件,就学习了下,在这里作个总结. 首先装简单介绍下DLL: 1,减小可执行文件的大小 DLL技术的产生有很大一部分原因是为了减小可执行 ...

  9. C# 调用外部dll(转)

    C# 调用外部dll   一.      DLL与应用程序 动态链接库(也称为DLL,即为"Dynamic Link Library"的缩写)是Microsoft Windows最 ...

随机推荐

  1. objc反汇编分析,手工逆向libsystem_blocks.dylib

    上一篇<block函数块为何物?>介绍了在函数中定义的block函数块的反汇编实现,我在文中再三指出__block变量和block函数块自始还都是stack-based的,还不完全适合在离 ...

  2. flex盒子布局

    看过很多对于弹性盒子flex的简介,但还是觉得阮一峰大神的解析和张鑫旭大神(旧版flex)的解析比较容易理解,下面,我以自己的理解来叙述关于flex弹性布局! 1.概念(容器和项目) 在flex中,有 ...

  3. 利用tomcat搭建图片服务器

    今天来教大家如何使用 tomcat 来搭建一个图片的服务器 1.先将tomcat解压一份并改名 2.此时apache-tomcat-8.5.43-windows-x64-file为图片服务器 依次打开 ...

  4. 剑指Offer-27.字符串的排列(C++/Java)

    题目: 输入一个字符串,按字典序打印出该字符串中字符的所有排列.例如输入字符串abc,则打印出由字符a,b,c所能排列出来的所有字符串abc,acb,bac,bca,cab和cba. 输入描述: 输入 ...

  5. CentOS7中安装MariaDB

    什么是mariaDB? 在线安装(慢的要命) RPM离线安装(CentOS7.X) 在线安装 打开官方网站 https://mariadb.org/ 点击Download,跳转到下一页面 继续点击Do ...

  6. 查找节点(getAttribute())

    getAttribute():方法将返回一个给定元素的一个给定属性节点的值: attributeValue = element.getAttribute(attributeName); 给定属性的名字 ...

  7. vsftp安装和配置

    2013-10-10 10:49:48|  分类: Linux|举报|字号 订阅     源码下载地址:ftp://vsftpd.beasts.org/users/cevans/untar/   1. ...

  8. vue使用tips

    1. native修饰符可以用来绑定原生事件 2. destroyed在列表重渲染时,销毁的列表项会调用. 3. 并不是所有的数据都适合放入vuex 4. 子组件mounted先于父组件发生. 5. ...

  9. UML类图绘制

    UML图简介 含义:UML-Unified Modeling Language 统一建模语言,又称标准建模语言.是用来对软件密集系统进行可视化建模的一种语言 主要模型: 功能模型:从用户的角度展示系统 ...

  10. 侠梦说pinpoint--界面上的图标之AgetnInfo数据研究

    前言 在启动一个挂载pinpoint的springboot项目的时候,界面上显示成了jboss的图标,所以今天研究了一下这个数据是怎么来的. 我们知道不同图标和服务类型有关,服务不同,图标就不同,这在 ...