c++ 非托管程序调用c#托管程序l的实现操作方式

        最近,做产品开发,需要在非托管的c++程序调用c#的托管程序。经过试验,整理了一种简便方法,但该方法局限比较多,后面会推荐另外一个方式。现在先介绍该方法的操作步骤如下:

       1.创建c#的dll中接口的定义参看下面的示例。注意接口中的函数必须为静态的函数,输入参数只能有一个字符串类型,返回值必须为int,具体参看下面说明。

using System.IO;
using System.Xml;
using System.Data;
namespace CLRLib
{
    /// <summary>
    /// 此类为和c++交互的接口类,成员函数均为静态函数
    /// </summary>
    class cgCLRLibAccessAdapter
    {


        /// <summary>
        /// 测试
        /// </summary>
        /// <param name="szParam">标志参数</param>
        /// <returns>返回值</returns>
//  备注:接口函数只能为静态函数,返回值只能为Int,输入参数只能有一个字符串
        public static Int32 IsTest(String szParam)
        {
    int i= 2;
                return i;
}
     }
}

    2.定义了类cgCLRAccess用来操作访问c#类的函数。具体类的定义参看附件文件cgCLRAcess.h和cgCLRAcess.cpp。

文件cgCLRAcess.h:

#pragma once
#include "stdafx.h"
#include <MSCorEE.h>
//=========================================================================
//访问CLRDll的相关类
class cgCLRAccess
{
private:
CString m_szFileName;   //动态库文件全名
CString m_szClassName;  //c#类名称
ICLRRuntimeHost *m_pClrHost; //CLR运行时态宿主
CString m_szNetFrameVersion; //dll的目标FrameWork版本
public:
cgCLRAccess(CString fileName,CString className,CString netFrameVersion);
~cgCLRAccess();
//运行方法
int RunMethod(CString szMethodName,CString szParamString);
};

文件cgCLRAcess.cpp:

#include "StdAfx.h"
#include "cgCLRAccess.h"
#include <Windows.h>
#include <assert.h>
#include <Windows.h>
#include <MSCorEE.h>


using namespace std;


#pragma comment(lib,"mscoree.lib")
// ---------------------------------------------------------------
// 名称: cgCLRAccess
// 功能: 构造函数
// 变量: [in] fileName -- dll文件名
// [in] className -- 类名,包含命名空间
// [in] netFrameVersion -- NetFrame版本号
// 返回: 返回值int表示结果,-1,表示运行方法失败
// 编写: 张伟强,20170725
// ---------------------------------------------------------------
cgCLRAccess::cgCLRAccess(CString fileName,CString className,CString netFrameVersion)
{
m_szFileName=fileName;
m_szClassName=className;
m_szNetFrameVersion=netFrameVersion;
m_pClrHost =NULL;
//注意只能调用一次,第一个需要传递c#dll的.net framework版本号,缺省空为2.0
HRESULT hr = CorBindToRuntimeEx(m_szNetFrameVersion,
NULL,0,
CLSID_CLRRuntimeHost,
IID_ICLRRuntimeHost,
(PVOID*)&m_pClrHost);


if(hr != S_OK||hr != S_FAILED)
{
m_pClrHost = NULL;
return;
}
if(m_pClrHost)
{
hr=m_pClrHost->Start();
}
}
cgCLRAccess::~cgCLRAccess()
{
if(m_pClrHost != NULL)--只能加载一次
{
m_pClrHost->Stop();
m_pClrHost->Release();
}
}
// ---------------------------------------------------------------
// 名称: RunMethod
// 功能: 运行方法
// 变量: [in] szMethodName -- 方法名称
// [in] szParamString -- 方法参数
// 返回: 返回值int表示结果,-1,表示运行方法失败
// 编写: 张伟强,20170725
// ---------------------------------------------------------------
int cgCLRAccess::RunMethod(CString szMethodName,CString szParamString)
{
DWORD retVal=0;
//将dll加载到默认应用程序域中,并调用其中的方法
HRESULT hr = m_pClrHost->ExecuteInDefaultAppDomain(m_szFileName,m_szClassName,szMethodName,
szParamString,&retVal);
//后面增加错误处理
if(hr!=S_OK)
{
retVal = -1;
}
return retVal;
}

   3.c++调用的代码如下:
CString szParam=_T("test");
// 需要注意,这个类只能定义一次。_T("v4.0.30319")为c#依赖的.NetFrame版本号,如果传递错误,则会导致后面运行ExecuteInDefaultAppDomain出错,错误代码-2146234341或者FFFFFFFF8013101B。CLRLib.dll 为dll库的文件名,需要时要带路径
cgCLRAccess clrAccess(_T("CLRLib.dll"),_T("CLRLib.cgCLRLibAccessAdapter"),_T("v4.0.30319"));
int nRet =clrAccess.RunMethod(_T("IsTest"),szParam);

   按照以上操作,就完成了整个过程。以上,是我的学习过程遇到的问题和解决办法,记录下来防止自己忘记,同时也与大家分享,免走弯路。

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

余山水

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值