一般在网上搜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. EF6+MYSQL之初体验

    初次使用EF6+MYSQL 这次的项目时间可拉得够长的,定制开发就是这样.客户真正用上了才能基本上不再改了.起先项目是php实现的,改造成桌面程序.用.net winform开发,像这种小项目肯定要用 ...

  2. crontab 定时调度

    crontab -e */1 8-23 * * * /www/target/sh/myorder.sh & 0 1 * * * /www/target/php/sh/mymoney.sh &a ...

  3. Sharepoint 2013列表视图和字段权限扩展插件(免费下载)!

    记得2014年春节期间,有博客园的网友通过QQ向我咨询Sharepoint 2013列表视图和字段权限扩展,因为之前他看到我博客介绍Sharepoint 2010列表视图和字段的权限控制扩展使用,问有 ...

  4. ping: sendto: Network is unreachable

    在我的板子上ping路由上的IP的时候可以ping通,但是ping外网的IP的时候提示"ping: sendto: Network is unreachable" 后来使用rout ...

  5. Application MyTest has not been registered. This is either due to a require() error during initialization or failure to call AppRegistry.registerComponent.

    运行react-native项目时报错. 说明一下:项目本来是好的,再次运行就报错了 解决解决办法倒是有,不过具体什么原因不知道.希望有知道具体原因的童鞋能够补充一下 第一种情况:真的是注册的时候写错 ...

  6. java nio 网络框架

    https://github.com/solq360/common 主要运行在android 平台 解决自动化编/解码,等等.. 模块 解决问题/实现处理 备注 负责人 进度 录音播放 AudioRe ...

  7. java 实现验证码

    package edu.zzuli.common; import java.awt.Color; import java.awt.Font; import java.awt.Graphics2D; i ...

  8. 【转】Oracle RAC 环境下的连接管理

    文章转自:http://www.oracle.com/technetwork/cn/articles/database-performance/oracle-rac-connection-mgmt-1 ...

  9. 【软件分析与挖掘】Vision of Software Clone Management: Past, Present, and Future (Keynote Paper)

    abstract: 代码克隆的综述 S1    INTRODUCTION AND MOTIVATION 代码克隆的利弊: 利:可以有效地去耦合,避免其他一些可能的错误: 弊:当被复制的那段code中带 ...

  10. [mysql]MySQL忘记密码

    1.修改MySQL的登录设置: vi /etc/my.cnf 在[mysqld]的段中加上一句:skip-grant-tables 保存并且退出vi. 2.重新启动mysqld # /etc/init ...