COM與.NET的互操作(初級)
2024-07-10 12:59:42
供稿:網友
 
com與.net的互操作(初級)
com與.net的互操作中從.net調用com組件,如果使用vs.net將變得非常容易,你只需要在你的工程中,添加對應的com引用,編譯工具就在后臺悄悄的把com“變成”了.net程序集。而從傳統的語言調用調用.net組件卻不如那么方便了。所以,我整理了個人調試成功的幾段程序希望對大家有一些幫助,好了廢話少說進入正題。
 
一,從vbscript等腳本調用.net組件
首先我們可以寫一個.net dll如下
//the first file:netserver.cs 
using system;
using system.reflection;
using system.runtime.interopservices;
 
[assembly: assemblykeyfile("key.snk")]
namespace csharpserver
{ 
 //缺省的是classinterfacetype.autodispatch,該方式下只生成dispatch接口
 //只能被使用script、vb等late binding方式的com客戶使用
 [classinterfaceattribute(classinterfacetype.autodual)] 
 public class sharpobject
 {
 private string m_strname;
 
 public sharpobject(){}
 
 public string name //property: name, get/set
 {
 get { return m_strname; }
 set { m_strname = value; }
 }
 }
}
 
//the second file: test.vbs
dim obj 
set obj = createobject("csharpserver.sharpobject") 
obj.name = "chang ming"
msgbox "my name is " & obj.name
 
對這兩個文件按如下方式編譯,為了清晰起見我們使用命令行工具(命令行工具環境可以從開始——>microsoft visual studio .net——>visual studio .net 工具——>visual studio .net 命令提示中進入)
1,生成密鑰文件,用于給程序集強名稱簽名
sn -k key.snk
 
2,使用強名稱簽名,編譯成類庫,
csc /t:library netserver.cs
 
3,生成類型庫
tlbexp netserver.dll /out:netserver.tlb
 
4,注冊dll
regasm netserver.dll
 
5,移入gac全局程序集緩存
gacutil -i netserver.dll
 
6,調用測試腳本
wscript test.vbs
 
在這里有幾個需要注意的地方,1,必須要給程序集簽名,讓它具有強名稱。2,必須將使用regasm注冊程序集,它將會在注冊表中添加相應的項。3,必須將簽名后的強名稱程序集移入全局程序集緩存(gac)。4,必須要先安裝scriptengine了,微軟的腳本執行引擎。這是從腳本調用.net 程序集了,呵呵,很簡單吧?j
 
二,從c/c++調用.net組件
還是一段程序,呵呵,程序就是我的生命:)
//file1 name:netserver.cs
using system;
using system.reflection;
using system.runtime.interopservices;
 
[assembly: assemblykeyfile("key.snk")]
namespace csharpserver
{ 
 
 public interface iobject //聲明接口
 {
 double sub(double c,double d);
 } 
 
//[classinterfaceattribute(classinterfacetype.autodual)] 
 
 public class sharpobject:iobject
 {
 private string m_strname;
 
 public sharpobject(){}
 
 public string name //property: name, get/set
 {
 get { return m_strname; }
 set { m_strname = value; }
 }
 
 public double add(double a,double b)
 {
 console.writeline("the answer is {0}",a+b);
 return a+b;
 }
 public double sub(double c,double d) //實現接口方法
 {
 console.writeline("the answer is {0}",c-d);
 return c-d;
 }
 }
}
 
 
//file2 name: comclient.cpp
#include <windows.h>
#include <stdio.h>
#include <iostream.h>
#pragma warning (disable: 4278)
 
#import "netserver.tlb" no_namespace named_guids
 
int main(int argc, char* argv[])
{
 iobject *cpi = null;
 int retval = 1;
 
 // initialize com and create an instance of the interfaceimplementation class:
 coinitialize(null);
 hresult hr = cocreateinstance(clsid_sharpobject,
 null,
 clsctx_inproc_server,
 iid_iobject,
 reinterpret_cast<void**>(&cpi));
 
 if (failed(hr))
 {
 printf("couldn't create the instance!... 0x%x/n", hr);
 }
 else
 {
 
 printf("calling function./n");
 
 retval = 0;
 cout<<"10-4="<<cpi->sub(10,4)<<endl;
 printf("returned from function./n");
 
 cpi->release();//釋放com對象
 }
 
 // be a good citizen and clean up com:
 couninitialize();
 return retval;
}
 
編譯方法還是如前
1,生成密鑰文件,用于給程序集強名稱簽名
sn -k key.snk
 
2,使用強名稱簽名,編譯成類庫,
csc /t:library netserver.cs
 
3,生成類型庫 //這一步很重要
tlbexp netserver.dll /out:netserver.tlb
 
4,注冊dll
regasm netserver.dll
 
5,移入gac全局程序集緩存
gacutil -i netserver.dll
 
6,編譯測試程序
cl comclient.cpp
7,執行comclient.exe
 
說明:
在c/c++中調用com要麻煩一些,首先要調用com庫函數coinitialize(null);進行初始化,然后調用hresult hr = cocreateinstance(clsid_sharpobject,
 null,
 clsctx_inproc_server,
 iid_iobject,
 reinterpret_cast<void**>(&cpi));
其中clsid_sharpobject是sharpobject類(com類)的類id它是由工具生成的用來唯一標識sharpobject類,iid_iobject唯一標識iobject接口,如果cocreateinstance成功的創建了com對象,那么failed(hr)將為false,得到com對象的指針后,就可以用它調用com對象中的方法了.
本文來源于網頁設計愛好者web開發社區http://www.html.org.cn收集整理,歡迎訪問。