国产探花免费观看_亚洲丰满少妇自慰呻吟_97日韩有码在线_资源在线日韩欧美_一区二区精品毛片,辰东完美世界有声小说,欢乐颂第一季,yy玄幻小说排行榜完本

首頁 > 開發(fā) > 綜合 > 正文

用C#創(chuàng)建COM對象(轉(zhuǎn)自計算機(jī)世界)

2024-07-21 02:24:19
字體:
供稿:網(wǎng)友
在本篇文章中,我們將討論下面的問題:
·使用c#創(chuàng)建一個簡單的com對象(使用com的interop特性)。
·從vc++客戶端軟件中訪問com。客戶端軟件使用了typelibrary(.tlb文件)。
為了簡單和方便開發(fā)人員使用、測試起見,我們使用了sqlserver數(shù)據(jù)庫軟件的缺省安裝中的northwind數(shù)據(jù)庫。
·修改com對象中sqlserver的名字,與sqlserver連接。
·我們已經(jīng)創(chuàng)建了連接數(shù)據(jù)庫用的分別為scott、tiger的用戶名和口令,我們可以使用它或者其他現(xiàn)有的用戶名和口令。
第一部分:用c#創(chuàng)建簡單的com對象
com對象是classlibrary類,它生成dll文件。要在vs開發(fā)環(huán)境中創(chuàng)建一個簡單的com對象,我們可以依次選擇“文件”->“新創(chuàng)建”->“工程”->“visualc#工程”->“類庫”,然后創(chuàng)建一個名字為database_comobject的工程。

需要注意的是:在com中調(diào)用vc#對象需要下面的條件:
·類必須是public性質(zhì)。
·特性、方法和事件必須是public性質(zhì)的。
·特性和方法必須在類接口中定義。
·事件必須在事件接口中定義。
不是在這些接口中定義的public性質(zhì)的類成員不能被com訪問,但它們可以被其他的.net framework對象訪問。要讓com能夠訪問特性和方法,我們必須在類接口中定義它們,使它們具有dispid屬性,并在類中實現(xiàn)這些特性和方法。這些成員定義時的順序也就是它們在com中順序。要讓com訪問類中的事件,必須在事件接口中定義這些事件,并賦予它們dispid屬性。事件接口不應(yīng)當(dāng)由類完成,類只實現(xiàn)類接口(它可以實現(xiàn)不止一個接口,但第一個接口是缺省接口),應(yīng)當(dāng)在缺省接口中實現(xiàn)需要讓com訪問的方法和特性,方法和特性必須被標(biāo)識為public性質(zhì),并符合在類接口中的定義。需要讓com訪問的事件也在缺省的類接口中完成,它們也必須被標(biāo)識為public性質(zhì),并符合事件接口中的定義。
在接口名字之前,每個接口需要一個guid特性。要生成變個唯一的guid,需要運(yùn)行g(shù)uidgen.exe工具軟件,并選擇“注冊表格式”
下面是一個類界面:

[guid("694c1820-04b6-4988-928f-fd858b95c880")]
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);
}



com事件接口:
// 事件接口database_comobjectevents  
[guid("47c976e0-c208-4740-ac42-41212d3c34f0"),  
interfacetype(cominterfacetype.interfaceisidispatch)]
public interface dbcom_events  
{
}


下面是實際的類定義:

[guid("9e5e5fb2-219d-4ee7-ab27-e4dbed8e123e"),
classinterface(classinterfacetype.none),
comsourceinterfaces(typeof(dbcom_events))]
public class dbcom_class : dbcom_interface
{


需要注意的是,在類的前面,需要設(shè)置下面的特性:

classinterface(classinterfacetype.none),
comsourceinterfaces(typeof(dbcom_events))]

classinterfacetype.none表示沒有為該類生成類接口,如果沒有明確地實現(xiàn)接口,類只能通過idispatch提供后期綁定訪問。用戶希望通過明確地由類實現(xiàn)的接口使外部對象能夠訪問類的功能,這也是推薦的classinterfaceattribute的設(shè)置。
comsourceinterfaces(typeof(dbcom_events))]確定許多作為com事件向外部對象提供的接口。在本文的例子中,我們不對外部對象開放任何事件。

下面是com對象完整的源代碼:

using system;
using system.runtime.interopservices;
using system.io;
using system.text;
using system.data.sqlclient;
using system.windows.forms ;

namespace database_comobject
{
[guid("694c1820-04b6-4988-928f-fd858b95c880")]
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);
}

// 事件接口database_comobjectevents  
[guid("47c976e0-c208-4740-ac42-41212d3c34f0"),  
interfacetype(cominterfacetype.interfaceisidispatch)]
public interface dbcom_events  
{
}


[guid("9e5e5fb2-219d-4ee7-ab27-e4dbed8e123e"),
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();
}

}
}


在創(chuàng)建com對象前,我們必須向com interop注冊該對象。右擊方案管理器中的工程名字,點擊快捷菜單上的“屬性”選項,然后再點擊“配置”->“創(chuàng)建”,擴(kuò)展output小節(jié),將register for com interop選項的值設(shè)置為true。這樣,一個com對象就能夠與可管理性應(yīng)用程序進(jìn)行交互。

為了使com對象能夠被外部對象調(diào)用,類庫組合必須有一個強(qiáng)名字。創(chuàng)建強(qiáng)名字需要用到sn.exe名字:
sn -k database_com_key.snk
打開assemblyinfo.cs,并修改下面一行的內(nèi)容:
[assembly: assemblykeyfile("database_com_key.snk")]

創(chuàng)建對象。創(chuàng)建對象會生成一個可以被導(dǎo)入到可管理性或非可管理性代碼中的類庫。
第二部分:使用visual c++創(chuàng)建訪問com對象的客戶端軟件
·使用vc++開發(fā)環(huán)境創(chuàng)建一個簡單的工程。
·使用#import directive導(dǎo)入類型庫。
·在界面中創(chuàng)建一個smart pointer,從接口中執(zhí)行com類提供的功能。確保在應(yīng)用程序加載時添加coinitialize()調(diào)用:
coinitialize(null);

database_comobject::dbcom_interfaceptr p(__uuidof(database_comobject::dbcom_class));
db_com_ptr = p ;
db_com_ptr->init("scott" , "tiger");

下面的代碼對customers數(shù)據(jù)庫表執(zhí)行一個sql命令,返回給定id的客戶的信息:
char cmd[1024];
sprintf(cmd , "select companyname , contactname ,
contacttitle , address from customers where customerid = '%s'" , m_id );
const char *p ;

bool ret = db_com_ptr->executeselectcommand(cmd);

if ( ! db_com_ptr->nextrow() ) return ;

_bstr_t mdata = db_com_ptr->getcolumndata(3);
p = mdata ;
m_address = (cstring)p ;
,歡迎訪問網(wǎng)頁設(shè)計愛好者web開發(fā)。
發(fā)表評論 共有條評論
用戶名: 密碼:
驗證碼: 匿名發(fā)表
主站蜘蛛池模板: 南和县| 黄龙县| 永宁县| 开江县| 靖边县| 宁津县| 临安市| 桦甸市| 礼泉县| 潜山县| 右玉县| 廊坊市| 香港 | 泰来县| 固原市| 渑池县| 建阳市| 睢宁县| 湟源县| 霍山县| 铜川市| 大邑县| 玉环县| 江津市| 通州区| 舒城县| 新巴尔虎右旗| 荣成市| 错那县| 和硕县| 霍邱县| 新河县| 沐川县| 蓬莱市| 泗水县| 白山市| 政和县| 绵阳市| 宁夏| 安丘市| 巴彦淖尔市|