最近朋友要求帮忙把一个C#写的dll转化成vc MFC可以调用的dll,原本以为很简单的事情,在百度上找了几天,都没有一个简单的方法。折腾了几天,通过网上找的资料加上自己以往的项目经验,终于做完,以下把步骤记录一下:
1.c#建立一个类库项目,项目名为CSharpToCom
2.把Class1类名改为CSharpClass
3.项目-->添加新项-->选择接口,接口名改为ICSharpInterface
4.修改ICSharpInterface.cs内容为
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Runtime.InteropServices;
namespace CSharpToCom
{
[Guid("7CC9E4F5-B560-48fb-98BA-E7A158AB0954")]
[InterfaceType(ComInterfaceType.InterfaceIsIDispatch)]
[ComVisible(true)]
public interface ICSharpInterface
{
[DispId(1)]
long MyAdd();
[DispId(2)]
long MyMessage(string message);
}
}
//注意:以上"7CC9E4F5-B560-48fb-98BA-E7A158AB0954"是唯一标志符,可以在vs命令提示符内输入guidgen选择Registry Format来产生
5.修改CSharpClass.cs文件内容为
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Runtime.InteropServices;
using System.Windows.Forms;
namespace CSharpToCom
{
[Guid("95982183-533F-40da-9D75-64F7C3C1E7F7")]
[ClassInterface(ClassInterfaceType.None)]
[ProgId("CSharpToCom")]
[ComVisible(true)]
public class CSharpClass:ICSharpInterface
{
public CSharpClass()
{
}
public long MyAdd()
{
return 11 + 22;
}
public long MyMessage(string message)
{
MessageBox.Show(message);
return 1;
}
}
}
//注意:以上"95982183-533F-40da-9D75-64F7C3C1E7F7"是唯一标志符,可以在vs命令提示符内输入guidgen选择Registry Format来产生
6.在项目上鼠标右键--->属性---->应用程序----->程序集信息
选中“使程序集COM可见(M)”
7.在项目上鼠标右键--->添加----->新建项
选择文本文件,修为名字为register_Com.bat
修改内容为:
REM register_Com.bat
REM copy this batch file to the same folder with CSharpToCom.dll
REM execute in elevated (run as administrator) Visual Studio Command Prompt
set REGASM_PATH=C:\Windows\Microsoft.NET\Framework\v4.0.30319
%REGASM_PATH%\regasm.exe CSharpToCom.dll /tlb:CSharpToCom.tlb
%REGASM_PATH%\regasm.exe CSharpToCom.dll /regfile
%REGASM_PATH%\regasm.exe CSharpToCom.dll
8.在项目上鼠标右键--->重新生成
生成后在bin\debug下面有CSharpToCom.dll
把register_Com.bat拷到bin\debug下
9.开始--->Visual Studio 命令提示(2010) ---> 鼠标右键--->以管理员身份运行
在命令提示符切换当前目录到bin\debug,运行register_Com.bat,产生CSharpToCom.reg、CSharpToCom.tlb等文件
10.vc上调用
新建VC MFC 对话框项目,添加Button1按钮。
11. 项目----->类向导--->添加类下拉菜单
选择 类型库中的MFC类
选择CSharpToCom.tlb 添加类
12.在对话框类的CPP文件里加上
#include "CCSharpInterface.h"
CCSharpInterface g_ICSharpInterface;
BOOL CComTestDlg::OnInitDialog()
{
CDialogEx::OnInitDialog();
// 将“关于...”菜单项添加到系统菜单中。
// IDM_ABOUTBOX 必须在系统命令范围内。
ASSERT((IDM_ABOUTBOX & 0xFFF0) == IDM_ABOUTBOX);
ASSERT(IDM_ABOUTBOX < 0xF000);
CMenu* pSysMenu = GetSystemMenu(FALSE);
if (pSysMenu != NULL)
{
BOOL bNameValid;
CString strAboutMenu;
bNameValid = strAboutMenu.LoadString(IDS_ABOUTBOX);
ASSERT(bNameValid);
if (!strAboutMenu.IsEmpty())
{
pSysMenu->AppendMenu(MF_SEPARATOR);
pSysMenu->AppendMenu(MF_STRING, IDM_ABOUTBOX, strAboutMenu);
}
}
// 设置此对话框的图标。当应用程序主窗口不是对话框时,框架将自动
// 执行此操作
SetIcon(m_hIcon, TRUE);// 设置大图标
SetIcon(m_hIcon, FALSE);// 设置小图标
// TODO: 在此添加额外的初始化代码
HRESULT coinit = CoInitialize(NULL);
LPCTSTR lpszProgId = _T("CSharpToCom");
g_ICSharpInterface.CreateDispatch(lpszProgId);
return TRUE; // 除非将焦点设置到控件,否则返回 TRUE
}
void CComTestDlg::OnBnClickedButton1()
{
// TODO: 在此添加控件通知处理程序代码
TRACE("%d\r\n",g_ICSharpInterface.MyAdd());
TRACE("%d\r\n",g_ICSharpInterface.MyMessage("abc"));
}
void CComTestDlg::OnClose()
{
// TODO: 在此添加消息处理程序代码和/或调用默认值
CoUninitialize();
CDialogEx::OnClose();
}