Part I: Creating a simple COM object in C#(Build一个C# dll)
Part II: Creating a Client using Visual C++ to access this COM Object(VC6++调用这个Dll);
step1:
New->Project->Visual C# Projects ->Class Library;命名为dll;project中会有一个Class1.cs
step2:将如下代码整个copy 到Class1.cs中
using System;
using System.Runtime.InteropServices;
using System.IO;
using System.Text;
using System.Data.SqlClient;
using System.Windows.Forms ;
namespace dll
{
[Guid("015FF730-4D0F-4c63-AF79-3F424475DCC1")]
public interface DBCOM_Interface
{
[DispId(1)]
void Init(string userid , string password);
[DispId(2)]
bool ExecuteSelectCommand(string selCommand);
[DispId(3)]
bool NextRow();
[DispId(4)]
void ExecuteNonSelectCommand(string insCommand);
[DispId(5)]
string GetColumnData(int pos);
//以下新增的函数----------------------
[DispId(6)]
void ShowMessage(int i);
//-----------------------------------------
}
// Events interface Database_COMObjectEvents
[Guid("EEBC550E-C6BF-405b-9ED5-CC67FEA31DF8"),
InterfaceType(ComInterfaceType.InterfaceIsIDispatch)]
public interface DBCOM_Events
{
}
[Guid("34980F11-0B67-4e24-A559-3BDB3B6D795A"),
ClassInterface(ClassInterfaceType.None),
ComSourceInterfaces(typeof(DBCOM_Events))]
public class DBCOM_Class : DBCOM_Interface
{
private SqlConnection myConnection = null ;
SqlDataReader myReader = null ;
public DBCOM_Class()
{
}
public void Init(string userid , string password)
{
try
{
string myConnectString = "user id="+userid+";password="+password+
";Database=NorthWind;Server=SKYWALKER;Connect Timeout=30";
myConnection = new SqlConnection(myConnectString);
myConnection.Open();
//MessageBox.Show("CONNECTED");
}
catch(Exception e)
{
MessageBox.Show(e.Message);
}
}
public bool ExecuteSelectCommand(string selCommand)
{
if ( myReader != null )
myReader.Close() ;
SqlCommand myCommand = new SqlCommand(selCommand);
myCommand.Connection = myConnection;
myCommand.ExecuteNonQuery();
myReader = myCommand.ExecuteReader();
return true ;
}
public bool NextRow()
{
if ( ! myReader.Read() )
{
myReader.Close();
return false ;
}
return true ;
}
public string GetColumnData(int pos)
{
Object obj = myReader.GetValue(pos);
if ( obj == null ) return "" ;
return obj.ToString() ;
}
public void ExecuteNonSelectCommand(string insCommand)
{
SqlCommand myCommand = new SqlCommand(insCommand , myConnection);
int retRows = myCommand.ExecuteNonQuery();
}
public void ShowMessage(int i)
{
MessageBox.Show("Hello,this is C# dll!");
}
}
}
step3: 修改工程的属性,在“Build”栏里钩上Register for COM Interop 。Then compile this project! success!
step4:在cmd命令中键入:cd C:/Program Files/Microsoft Visual Studio 8/SDK/v2.0/Bin(我使用的是VS2005),Enter后再输入sn -k dll.snk,此时您可以将C:/Program Files/Microsoft Visual Studio 8/SDK/v2.0/Bin 目录下新生成的dll.snk 文件copy到project的debug目录下,
step5:在将AssemblyInfo.cs文件中[assembly: ComVisible(false)]改成[assembly: ComVisible(true)], 最后一段改写成[assembly: AssemblyVersion("1.0.0.0")]
[assembly: AssemblyDelaySign(false)]
[assembly: AssemblyKeyFile("dll.snk")]
[assembly: AssemblyFileVersion("1.0.0.0")],重新compile.可以看到debug目录下生成一个新的dll.tlb文件。
step6: 新建一个C++ project,命名为exe我选用的是MFC的MFC Application,然后设置Application type为 Dialog based。将上述的dll.tlb文件copy 到这个工程目录下。
step7:在Resource view 中,打开Dialog视窗,加入OK button 事件,如下完整文件所示
// exeDlg.cpp : implementation file
//
#include "stdafx.h"
#include "exe.h"
#include "exeDlg.h"
#include <atlbase.h>//加入需要的头文件
using namespace ATL;
#ifdef _DEBUG
#define new DEBUG_NEW
#endif
// CexeDlg dialog
#import "dll.tlb"//加入的引用
CexeDlg::CexeDlg(CWnd* pParent /*=NULL*/)
: CDialog(CexeDlg::IDD, pParent)
{
m_hIcon = AfxGetApp()->LoadIcon(IDR_MAINFRAME);
}
void CexeDlg::DoDataExchange(CDataExchange* pDX)
{
CDialog::DoDataExchange(pDX);
}
BEGIN_MESSAGE_MAP(CexeDlg, CDialog)
ON_WM_PAINT()
ON_WM_QUERYDRAGICON()
//}}AFX_MSG_MAP
ON_BN_CLICKED(IDOK, &CexeDlg::OnBnClickedOk)
END_MESSAGE_MAP()
// CexeDlg message handlers
BOOL CexeDlg::OnInitDialog()
{
CDialog::OnInitDialog();
// Set the icon for this dialog. The framework does this automatically
// when the application's main window is not a dialog
SetIcon(m_hIcon, TRUE); // Set big icon
SetIcon(m_hIcon, FALSE); // Set small icon
// TODO: Add extra initialization here
return TRUE; // return TRUE unless you set the focus to a control
}
// If you add a minimize button to your dialog, you will need the code below
// to draw the icon. For MFC applications using the document/view model,
// this is automatically done for you by the framework.
void CexeDlg::OnPaint()
{
if (IsIconic())
{
CPaintDC dc(this); // device context for painting
SendMessage(WM_ICONERASEBKGND, reinterpret_cast<WPARAM>(dc.GetSafeHdc()), 0);
// Center icon in client rectangle
int cxIcon = GetSystemMetrics(SM_CXICON);
int cyIcon = GetSystemMetrics(SM_CYICON);
CRect rect;
GetClientRect(&rect);
int x = (rect.Width() - cxIcon + 1) / 2;
int y = (rect.Height() - cyIcon + 1) / 2;
// Draw the icon
dc.DrawIcon(x, y, m_hIcon);
}
else
{
CDialog::OnPaint();
}
}
// The system calls this function to obtain the cursor to display while the user drags
// the minimized window.
HCURSOR CexeDlg::OnQueryDragIcon()
{
return static_cast<HCURSOR>(m_hIcon);
}
void CexeDlg::OnBnClickedOk()
{
// TODO: Add your control notification handler code here
OnOK();
}
//以下这段为新加入的调用C#函数--------------
void CexeDlg::OnOK()
{
CoInitialize(NULL);
dll::DBCOM_InterfacePtr p(__uuidof(dll::DBCOM_Class));
p->ShowMessage(2);
CoUninitialize();
}
//------------------------------
然后在此文件的头文件中别忘记声明函数
protected:
HICON m_hIcon;
// Generated message map functions
virtual BOOL OnInitDialog();
afx_msg void OnPaint();
afx_msg HCURSOR OnQueryDragIcon();
DECLARE_MESSAGE_MAP()
virtual void OnOK();//此行为加入的
public:
afx_msg void OnBnClickedOk();
step8:compile this project.and run. Then messagebox will show. So it’s OK!
C++调用C#作成的dll
最新推荐文章于 2024-08-10 20:57:22 发布