关于这个问题找了好多地方,都只有第二种解决办法,可是我要返回一个字符串,没办法,继续找,最后还是在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. 使用ndk交叉编译android各平台版本的第三方库

    只要弄明白了ndk-bundle的目录结构,交叉编译的基本原理就可以自行编写脚本去编译了.从仓库拿下代码包后,一般在linux平台下编译当前平台使用的库,只要使用其自动配置脚本configure进行平 ...

  2. oracle中两个服务器连接中sys密码修改问题

    问题描述:orcl服务器要连接orclstd 想要sqlplus sys/410526@orclstd as sysdba 连接orclstd数据库,但是发现啥意思密码不对,就对sys密码进行重新设置 ...

  3. python3之递归实例

    一.利用递归求: 1+2+3+4+5...+n的前n项和 def recursion_sum_1(n): #当n = 1:和为1 #否则,n的和等同于 n + (n -1) if n == 1: re ...

  4. day 13 生成器函数 表达式 推导式

    今日主要内容 1. 生成器和生成器函数 生成器的本质就是迭代器 生成器的三种创建办法: 1.通过生成器函数 2.通过生成器表达式创建生成器 3.通过数据转换 2. 生成器函数: 函数中包含了yield ...

  5. 基于 HTML5 + WebGL 的地铁 3D 可视化系统

    前言 工业互联网,物联网,可视化等名词在我们现在信息化的大背景下已经是耳熟能详,日常生活的交通,出行,吃穿等可能都可以用信息化的方式来为我们表达,在传统的可视化监控领域,一般都是基于 Web SCAD ...

  6. PHP+Redis实现延迟任务,实现自动取消与完成订单

    简单定时任务解决方案:使用redis的keyspace notifications(键失效后通知事件) : (A)业务场景: 1.当一个业务触发以后需要启动一个定时任务,在指定时间内再去执行一个任务( ...

  7. Spring Boot整合Elasticsearch启动报错

    如果你遇见下面的错误,很可能是你的springboot和es版本关系不对应 ERROR 14600 --- [ main] .d.e.r.s.AbstractElasticsearchReposito ...

  8. day20191102笔记

    当日所学默写笔记: 1.select id="唯一,必须写,对应的接口方法名称" resultType="必须写,返回的类型是对应持久化数据层的全限定类名或者是其别名&q ...

  9. c 语言I博客作业02

    这个作业属于哪个课程 C语言程序设计1 这个作业要求在哪里 https://edu.cnblogs.com/campus/zswxy/SE2019-2/homework/8687 我在这个课程的目标是 ...

  10. python推导式pythonic必备【华为云技术分享】

    版权声明:本文为博主原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接和本声明. 本文链接:https://blog.csdn.net/devcloud/article/detai ...