1. C#调用C++ Dll
a. 编写Atl Com Dll,添加IDL接口及连接点接口,编译注册,若不注册,则无法将tlb添加进C#引用
b. 创建C# Library,将tlb导入至C#工程
c. 将接口拷贝至新的文件,删除不必要的属性
d. 创建Com对象
e. c++代码中创建Com对象
主要通过PINVOKE调用导出函数,网上资料挺多的,本人也不是很精通,略过....
2. C++调用C# Library
1). 方案1
在C++工程属性里设置公共语言运行库支持(常规页面), 改变编译选项(http://technet.microsoft.com/zh-cn/library/ms235211(v=vs.90).aspx)
然后再代码里动态载入C# library,创建(枚举)相关类型,调用方法
DWORD WINAPI LoadDotNetDll(LPVOID lpThreadParameter)
{
CoInitialize(NULL);
TCHAR buffer[MAX_PATH];
GetModuleFileName(NULL,buffer,MAX_PATH);
CString exeModuleName = buffer;
int index = exeModuleName.ReverseFind(_T('\\'));
CString dllName = exeModuleName.Left(index+1)+_T("CSAlarmLib.dll");
String^ strDllName = gcnew String((LPCTSTR)dllName);
Assembly^ dllModule = Assembly::LoadFile(strDllName);
//遍历Assembly里类
String^ typeName = gcnew String(_T("CSAlarmLib.AlarmCenter"));
Type^ type = dllModule->GetType(typeName);
System::Object^ obj = dllModule->CreateInstance(typeName,TRUE);
::OutputDebugString((LPCTSTR)CString(obj->ToString()));
//遍历AlarmCenter方法
String^ strMethod = gcnew String(_T("OnStart"));
MethodInfo^ method = type->GetMethod(strMethod);
array<Object^>^ myArray = gcnew array<Object^>(1){gcnew AtlTrayHost::TrayHost()};
AtlTrayHost::TrayHost^ trayHost = gcnew AtlTrayHost::TrayHost();
//myArray->Insert(0,trayHost);
method->Invoke(obj, myArray);
return 0;
}
using namespace System;
#using "JieKouLib.dll"
using namespace JieKouLib;
namespace AtlTrayHost {
/// <summary>
/// ClrCls 摘要
/// </summary>
public ref class TrayHost : public ITrayHost
{
public:
virtual void OnReceive(String^ strXml)
{
::OutputDebugString((LPCTSTR)CString(strXml));
}
};
}
a. 编写Atl Com Dll,添加IDL接口及连接点接口,编译注册,若不注册,则无法将tlb添加进C#引用
b. 创建C# Library,将tlb导入至C#工程
c. 将接口拷贝至新的文件,删除不必要的属性
//IAgentTrayPlugin.cs
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Runtime.InteropServices;
namespace TrayPluginLib
{
[Guid("D3BF29BC-A706-430B-AAB4-9D9DE6BCD861")]
[InterfaceType(1)]
public interface IAgentTrayPlugin
{
void Send(string bstrXml);
}
}
//IAgentTrayPluginEvents.cs
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Runtime.InteropServices;
namespace TrayPluginLib
{
public delegate void Receive(string bstrXml);
[InterfaceType(1)]
[Guid("6330974C-E92C-4E49-8AC8-7F756DE23A33")]
public interface _IAgentTrayPluginEvents
{
void OnReceive(string bstrXml);
}
}
d. 创建Com对象
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Runtime.InteropServices;
using System.Windows.Forms;
using TrayPluginLib;
namespace AlarmCenterLib
{
[Guid("3D1FC18A-D2C2-40BF-8B1E-A29B428A78E6"),
ComSourceInterfaces(typeof(_IAgentTrayPluginEvents))]
public class AlarmCenterPlugin : IAgentTrayPlugin
{
public event Receive OnReceive;
public void Send(string bstrXml)
{
if (OnReceive!=null)
{
OnReceive(bstrXml);
}
}
}
}
e. c++代码中创建Com对象