一般在网上搜C++如何调用C#的函数,出来的结果都是做成COM组件,但是这种方法dll安装麻烦,需要注册COM组件,需要管理员权限,调试麻烦,经常需要重启机器,反正有诸多不便。

然后在看《CLR via C#》时看到一种方法,可以免去这种苦恼。少废话,先上代码。

C#类库的:

namespace ClassLibrary1
{
public class Class1
{
public static int pwzMethodName(String pwzArgument)
{
//Thread.Sleep(10000);
Console.WriteLine(pwzArgument);
Console.WriteLine(Thread.GetDomain().FriendlyName);
}
}
}

C++调用代码:

#include <metahost.h>
#include <fstream>
using namespace std; #pragma comment(lib, "mscoree.lib") int _tmain(int argc, _TCHAR* argv[])
{
ICLRMetaHost *pMetaHost = nullptr;
ICLRMetaHostPolicy *pMetaHostPolicy = nullptr;
ICLRRuntimeHost *pRuntimeHost = nullptr;
ICLRRuntimeInfo *pRuntimeInfo = nullptr; HRESULT hr = CLRCreateInstance(CLSID_CLRMetaHost, IID_ICLRMetaHost, (LPVOID*)&pMetaHost);
hr = pMetaHost->GetRuntime(L"v4.0.30319", IID_PPV_ARGS(&pRuntimeInfo)); if(FAILED(hr)) {
MessageBox(,L"启动出错",L"Error",MB_OK|MB_ICONERROR);
goto cleanup;
} hr = pRuntimeInfo->GetInterface(CLSID_CLRRuntimeHost, IID_PPV_ARGS(&pRuntimeHost));
hr = pRuntimeHost->Start(); DWORD dwRet = ;
hr = pRuntimeHost->ExecuteInDefaultAppDomain(L"ClassLibrary1.dll", //不会产生新的进程
L"ClassLibrary1.Class1",
L"pwzMethodName",
L"nimei",
&dwRet);
hr = pRuntimeHost->Stop(); cleanup:
if(pRuntimeInfo != nullptr) {
pRuntimeInfo->Release();
pRuntimeInfo = nullptr;
} if(pRuntimeHost != nullptr) {
pRuntimeHost->Release();
pRuntimeHost = nullptr;
} if(pMetaHost != nullptr) {
pMetaHost->Release();
pMetaHost = nullptr;
}
}

C#的代码就不解释了,就是提供一个int ClassLibrary1.Class1.pwzMethodName(String)的这样一个方法。

重点看一下C++,它的思路就是通过metahost.h中的函数来操作clr环境。

第一句,CLRCreateInstance(CLSID_CLRMetaHost, IID_ICLRMetaHost, (LPVOID*)&pMetaHost) 来初始化CLR环境,得到返回值pMetaHost。

第二句,pMetaHost->GetRuntime(L"v4.0.30319", IID_PPV_ARGS(&pRuntimeInfo)) 来指定运行时,第一个参数.NET版本号,必须和你的C#dll的版本号兼容,而且 此参数必须与显示在 C:\Windows\Microsoft.NET\Framework 或 C:\Windows\Microsoft.NET\Framework64 下的 .NET Framework 版本目录名称相匹配。比如,你的dll是用4.0编译的,而你的Framework目录有一下文件夹:v2.0.50727   v3.0   v3.5   v4.0.30319 ,所以这里的参数就是“v4.0.30319”,而且v是必须的。

第三句,pRuntimeInfo->GetInterface(CLSID_CLRRuntimeHost, IID_PPV_ARGS(&pRuntimeHost)) 将 CLR 加载到当前进程中,并返回运行时接口指针pRuntimeHost。

第四句,pRuntimeHost->Start() 将公共语言运行时 (CLR) 初始化到进程中。

第五句,pRuntimeHost->ExecuteInDefaultAppDomain

HRESULT ExecuteInDefaultAppDomain (
[in] LPCWSTR pwzAssemblyPath,
[in] LPCWSTR pwzTypeName,
[in] LPCWSTR pwzMethodName,
[in] LPCWSTR pwzArgument,
[out] DWORD *pReturnValue
);

pwzAssemblyPath是C#类库的路径和文件名,pwzTypeName是命名空间和类名,pwzMethodName是要调用的方法名称,pwzArgument是要传入的参数名称,pReturnValue是函数返回值。

后面的都是释放语句。

一般看来,这种方法只能调用int function(String para)这样的函数,但是实际上LPCWSTR 是WCHAR *,既然是指针就可以传递对象,同样返回值也可以是结构体或者数组。

本例地址:http://files.cnblogs.com/files/chihirosan/CPPCS%E4%BA%A4%E4%BA%92.rar

C++调用C#dll类库中的方法(非显性COM)的更多相关文章

  1. js调DLL类库中的方法实现(非com组件形式)

    1.首先,创建一个Web空项目 2.添加一个html或aspx页面 3.页面代码如所示: <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Tr ...

  2. 在SQL Server中使用CLR调用.NET类库中的方法 (转载)

    在SQL Server中调用 .NET 类库的方法要分为下面几步来实现: 在.NET中新建一个类库项目,并在这个项目中添加一个类文件,并把要被SQL Server调用的方法定义为公有的,静态的方法. ...

  3. Java调用第三方dll文件的使用方法 System.load()或System.loadLibrary()

    Java调用第三方dll文件的使用方法 public class OtherAdapter { static { //System.loadLibrary("Connector") ...

  4. js调用父级frame中的方法

    父级frame中的方法: function hideOutline() { $("#outline").hide(); $("#content").attr(& ...

  5. Python_Selenium 之以login_page为例实现对basepage封装好的方法调用和对common中公共方法的调用

    目的:简化代码,提供框架该有的东西每一个函数 -提供了一个功能 - 公共的功能有了basepage,在PageObjects当中直接调用元素操作. 以下以login_page 为例,实现从配置文件中读 ...

  6. C#实现反射调用动态加载的DLL文件中的方法

    反射的作用:1. 可以使用反射动态地创建类型的实例,将类型绑定到现有对象,或从现有对象中获取类型 2. 应用程序需要在运行时从某个特定的程序集中载入一个特定的类型,以便实现某个任务时可以用到反射.3. ...

  7. Python 调用 C# dll库最简方法

    1.为什么要跨平台编程?双平台编程或多平台编程,只是为提供更好开发更兼容的解决方案的一种手段,编程时服务于产品和客户的,也是因地制宜. 先安装python所需的库clr ,我这里已经安装了,可以去对应 ...

  8. go 调用windows dll 的三种方法

    参考:https://blog.csdn.net/qq_39584315/article/details/81287669 大部分代码参考:https://studygolang.com/articl ...

  9. Java中的一个类怎么调用另一个类中的方法

    如果另一个类中的那个方法是私有的话,就不能直接调用到,如果是其他类型的话看情况,如果是静态的(static)话,直接用类名可以调用到,如果是非静态的,就需要利用另一个类的实例(也就是用那个类生成的对象 ...

随机推荐

  1. java之接口interface

    接口 1.多个无关的类可以实现同一个接口 2.一个类可以实现多个无关的接口 3.与继承关系类似,接口与实现类之间存在多态性 4.定义java类的语法格式 < modifier> class ...

  2. DiskGenius无损调整分区大小

    一般情况下,调整分区的大小,通常都涉及到两个或两个以上的分区.比如,要想将某分区的大小扩大,通常还要同时将另一个分区的大小缩小:要想将某个分区的大小缩小,则通常还要同时将另一个分区的大小扩大.    ...

  3. Android 使用NDK编译sipdroid Library

    sipdroid是一款开源的运行于Android平台上的voip,目前支持音频和视频通话: 项目拖管地址:http://code.google.com/p/sipdroid/ 下载源代码,导入ecli ...

  4. SNF开发平台WinForm之二-开发-单表表单管理页面-SNF快速开发平台3.3-Spring.Net.Framework

    2.1运行效果: 2.2开发实现: 2.2.1 这个开发与第一个开发操作步骤是一致的,不同之处就是在生成完代码之后,留下如下圈红程序,其它删除. 第一个开发地址:开发-单表表格编辑管理页面 http: ...

  5. LOD设置

    Level of detail: 使用多个不同复杂度的mesh来表示一个object,当物体离摄像机越远时,就是用更加low-detail的mesh,反之越近就越使用越精细的mesh. 组件:LOD ...

  6. AssetBundle系列——共享资源打包/依赖资源打包

    有人在之前的博客中问我有关共享资源打包的代码,其实这一块很简单,就两个函数: BuildPipeline.PushAssetDependencies():依赖资源压栈: BuildPipeline.P ...

  7. 《编写高质量代码:改善C#程序的157个建议》源码下载

    ==== 目录 前 言第一部分 语言篇第1章 基本语言要素 / 2建议1:正确操作字符串 / 2建议2:使用默认转型方法 / 6建议3:区别对待强制转型与as和is / 9建议4:TryParse比P ...

  8. Sphinx全文索引 第一节

    1 使用场景:用来解决站内搜索的一些应用场景. 网站中的搜索(站内搜索) 系统后台中的搜索 第一种方式:PHP——>MySQL 第二种方式:MySQL<——>Sphinx:PHP—— ...

  9. 用live writer写博客

    一.软件准备: 最新版的是Windows Live Writer 2012,但是不提供单独的安装包,它是和微软其它软件一起的(包括MSN.Window Move Maker等),软件大小为131M,官 ...

  10. Pace.js – 超赞的页面加载进度自动指示和 Ajax 导航效果

    在页面中引入 Pace.js  和您所选择主题的 CSS 文件,就可以让你的页面拥有漂亮的加载进度和 Ajax 导航效果.不需要挂接到任何代码,自动检测进展.您可以选择颜色和多种效果,有简约,闪光灯, ...