我现在有几个c#的类,假设CLASS1,CLASS2,CLASS3等,最后有一个CLASSALL类。里面有一个默认的构造函数,还有一个方法public int GetResult(string).我是想在VC++里或DELPHI里调用出这个函数出来。不知道具体方法。现在请教!
具体要求如下:
1、给出C#做成DLL和COM组件的具体过程(详细一点,最好有图码)
2、 给出VC6++或DELPHI7中具体的调用过程(要有代码)急!!!!!!在线等
具体要求如下:
1、给出C#做成DLL和COM组件的具体过程(详细一点,最好有图码)
2、 给出VC6++或DELPHI7中具体的调用过程(要有代码)急!!!!!!在线等
你在项目上点右键,选属性,有一个输出类型,选为类库,这里编译完了它就是DLL了
做成com,你的几个类必须继承于System.EnterpriseServices.ServicedComponent(对System.EnterpriseServices.dll引用)
然后用Sn工具给你的程序引入强名称,然后在AssemblyInfo.cs文件中加入[assembly: AssemblyKeyFileAttribute("请名称的路径")],编译,最后RegSvcs或者手工加入com组件
--给你一个例子--
using System;
using System.Text;
using System.IO;
using System.Security.Cryptography;namespace DESEncrypt
{
/// <summary>
/// DESEncrypt 的摘要说明。
/// </summary>
public class DESEncrypt
{
private byte[] Keys = {0x12, 0x34, 0x56, 0x78, 0x90, 0xAB, 0xCD, 0xEF};//默认密钥向量
public DESEncrypt()
{
//
// TODO: 在此处添加构造函数逻辑
//
}
/// <summary>
/// DES加密字符串
/// </summary>
/// <param name="encryptString">待加密的字符串</param>
/// <param name="encryptKey">加密密钥,要求为8位</param>
/// <returns>加密成功返回加密后的字符串,失败返回源串</returns>
public string EncryptDES(string encryptString,string encryptKey)
{
try
{
byte[] rgbKey = Encoding.UTF8.GetBytes(encryptKey.Substring(0,8));
byte[] rgbIV = Keys;
byte[] inputByteArray = Encoding.UTF8.GetBytes(encryptString);
DESCryptoServiceProvider dCSP = new DESCryptoServiceProvider();
MemoryStream mStream = new MemoryStream();
CryptoStream cStream = new CryptoStream(mStream,dCSP.CreateEncryptor(rgbKey,rgbIV),CryptoStreamMode.Write);
cStream.Write(inputByteArray,0,inputByteArray.Length);
cStream.FlushFinalBlock();
return Convert.ToBase64String(mStream.ToArray());
}
catch
{
return encryptString;
}
}
/// <summary>
/// DES解密字符串
/// </summary>
/// <param name="decryptString">待解密的字符串</param>
/// <param name="decryptKey">解密密钥,要求为8位,和加密密钥相同</param>
/// <returns>解密成功返回解密后的字符串,失败返源串</returns>
public string DecryptDES(string decryptString,string decryptKey)
{
try
{
byte[] rgbKey = Encoding.UTF8.GetBytes(decryptKey);
byte[] rgbIV = Keys;
byte[] inputByteArray = Convert.FromBase64String(decryptString);
DESCryptoServiceProvider DCSP = new DESCryptoServiceProvider();
MemoryStream mStream = new MemoryStream();
CryptoStream cStream = new CryptoStream(mStream,DCSP.CreateDecryptor(rgbKey,rgbIV),CryptoStreamMode.Write);
cStream.Write(inputByteArray,0,inputByteArray.Length);
cStream.FlushFinalBlock();
return Encoding.UTF8.GetString(mStream.ToArray());
}
catch
{
return decryptString;
}
}
}
}
把你的文件内容拷贝覆盖系统自动生成的class1中,编译以后dll文件就会在debug--bin中生成
or use regasm command to regist a c# dll as a com.
但在VC.NET中可能会好用,但没具体作过,
楼上有人提过,COM确实可以一试
1、C#做出来的类库,和传统的dll不一样,所以无法在VC6或Delphi7中用LoadLibrary来调用;
2、C#做出来的Com+,和原先的com机制也不全一样。所以按照上面所走的两种方法,是基本行不通的。
稍微可行的办法是,用vc.net去写win32下的dll,然后给在VC6或Delphi7中用LoadLibrary来调用。
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.csstep2:将如下代码整个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 handlersBOOL 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!
看看这片文章还是比较容易的至少vc是这样,我不会delphi,不好说,不过和调用以前的com应该没有太大的区别,毕竟com是为了实现二进制的复用,对于使用者应该和具体用何种语言实现没有太大的关系
调用时客户端必须也要有.net的环境.....最好是用C++写吧!我就知道这样了,呵