常规方法1:COM
使用C#把托管类注册成COM,用regasm.exe注册output assembly,然后用C++像调用COM一样调用assembly里面的type。
优点:编写代码简单,调用方便
缺点:需要注册output,发布不够简单
常规方法2:CLR
C#常规编写类,生产assembly,C++使用CLR编译既可直接引用托管类。
优点:编写代码简单,调用方便
缺点:需要了解C++ CLR语法(既不像C++,又不像C#,总之很奇怪)
参考:http://www.codeproject.com/KB/mcpp/cppcliintro01.aspx ,http://msdn.microsoft.com/en-us/library/k8d11d4s.aspx
范例:
vc++调用端增加公共语言运行时【clr】的支持以执行C#的程序:解决方案-》Properties(右键)-》Configuration Properties(展开左树)->General(打开子节点)->Common Language Runtime support(选中选项)->【Common Language Runtime support(/clr)】(选中)
OK,现在就可以引入托管的动态连接库来用了,不过在调用时还是得注意语法(new->gcnew,....),例如下:
- #include "stdafx.h"
- #using "SmartDeviceDLL.dll"
- using namespace SmartDeviceDLL;
- int _tmain(int argc, _TCHAR* argv[])
- {
- printf("1111111111111/n");
- SmartDeviceDLL::ICalculator ^pICalc=gcnew SmartDeviceDLL::Class1();
- long lResult =0;
- lResult=pICalc->Add(5,10);
- wprintf(L"the result is %d/n",lResult);
- printf("222222222222222222/n");
- char c;
- scanf("%c",&c);
- return 0;
- }
常规方法3(推荐):API
C#常规编写类,生产assembly,C++使用SDK提供的CLR非托管接口(CLRCreateInstance)进行调用。
优点:传统C#编程,传统C++编程
缺点:暂时还没发现
范例:
C#
using System;
namespace ClassLibrary1
{
class Class1
{
static void Main(string[] args)
{
}
public static int Test(string s)
{
Console.WriteLine(s);
return 0;
}
}
}
C++
#include <Windows.h>
#include <stdio.h>
#include <iostream>
#include <assert.h>
#include <mscoree.h>
#include <metahost.h>
#pragma comment(lib, "mscoree.lib")
#define BUFFER_SIZE 500
#include "stdafx.h"
void StartTheDotNetRuntime(LPCWSTR runtimeVersion, LPCWSTR dllPath, LPCWSTR startClass, LPCWSTR startMethod, LPCWSTR startArgument)
{
ICLRMetaHost *pMetaHost = NULL;
//ICLRMetaHostPolicy *pMetaHostPolicy = NULL;
//ICLRDebugging *pCLRDebugging = NULL;
ICLRRuntimeInfo *pRuntimeInfo = NULL;
ICLRRuntimeHost *pRuntimeHost = NULL;
CLRCreateInstance(CLSID_CLRMetaHost, IID_ICLRMetaHost, (LPVOID*)&pMetaHost);
//CLRCreateInstance(CLSID_CLRMetaHostPolicy, IID_ICLRMetaHostPolicy, (LPVOID*)&pMetaHostPolicy);
//CLRCreateInstance(CLSID_CLRDebugging, IID_ICLRDebugging, (LPVOID*)&pCLRDebugging);
DWORD dwVersion = 0;
DWORD dwImageVersion = 0;
HRESULT hr;
hr = pMetaHost->GetRuntime(L"v4.0.30319", IID_ICLRRuntimeInfo, (LPVOID*)&pRuntimeInfo);
assert(SUCCEEDED(hr));
hr = pRuntimeInfo->GetInterface(CLSID_CLRRuntimeHost, IID_ICLRRuntimeHost, (LPVOID*)&pRuntimeHost);
assert(SUCCEEDED(hr));
hr = pRuntimeHost->Start();
assert(SUCCEEDED(hr));
DWORD dwRetCode = 0;
hr = pRuntimeHost->ExecuteInDefaultAppDomain(L"ClassLibrary1.dll",
L"ClassLibrary1.Class1",
L"Test",
L"Hello World!",
&dwRetCode);
assert(SUCCEEDED(hr));
pRuntimeHost->Stop();
pRuntimeHost->Release();
pRuntimeInfo->Release();
//pCLRDebugging->Release();
//pMetaHostPolicy->Release();
pMetaHost->Release();
}