1. 程式人生 > >COM/DCOM開發練習之程序外元件例項

COM/DCOM開發練習之程序外元件例項

1)使用C++語言實現程序外元件,組建提供加、減、乘、除、判斷是否素數等計算服務;客戶端部分包括錄入和查詢部分。

2VC++環境上利用ATL嚮導進行開發

2.程序外元件

  伺服器端:

  建立ATL工程:VC++->file->new->ATL COM AppWizar->服務型別選服務(service),如下圖所示:


  新增com物件, Insert-New ATL Object,新增shortname:calmath,其他則會自動新增;

在工作空間中,選擇com介面(即Icalmath),右鍵->ADD methods,新增提供的服務(方法)

輸入Method Name:add

Parameters:[in] int Num1, [in] int Num2, [out] int *result

如下圖所示:

按照同樣方法,新增方法:submultiplydividesushu

如下圖所示:


開啟calmath.cpp檔案(雙擊新增的方法即可開啟),寫入實現方法的程式碼:

calmath的程式碼如下:

// calmath.cpp : Implementation of Ccalmath
#include "stdafx.h"
#include "OutCalculator.h"
#include "calmath.h"
/////////////////////////////////////////////////////////////////////////////
// Ccalmath
int issushu(int s)
{
int i;
if(s==2||s==1) return 1;
for(i=2;i<sqrt(s);i++)
{
if(s%i==0) return 0;
}
return 1;
}
STDMETHODIMP Ccalmath::add(int Num1, int Num2, int *result)
{
// TODO: Add your implementation code here
    *result=Num1+Num2;
return S_OK;
}
STDMETHODIMP Ccalmath::sub(int Num1, int Num2, int *result)
{
// TODO: Add your implementation code here
    *result=Num1-Num2;
return S_OK;
}
STDMETHODIMP Ccalmath::multiply(long Num1, long Num2, long *result)
{
// TODO: Add your implementation code here
    *result=Num1*Num2;
return S_OK;
}
STDMETHODIMP Ccalmath::divide(long Num1, long Num2, long *result)
{
// TODO: Add your implementation code here
    *result=Num1/Num2;
return S_OK;
}
STDMETHODIMP Ccalmath::sushu(int Num, int *result)
{
// TODO: Add your implementation code here
    *result=issushu(Num1);
return S_OK;
}


  編譯連線


在工程debug目錄中可找到OutCalculator.exe元件

  使用OutCalculator.exe/RegServer /Service 註冊服務

  net start OutCalculator     啟動服務

如下圖所示:

  



客戶端:

新建一個win32 console application工程,工程名稱為:OutClient,工程目錄與伺服器端工程目錄相同;

新建一個cpp檔案,名稱為:client.cpp,儲存到當前工程中;

編寫client.cpp的程式碼:

//#define  _WIN32_WINNT  0x0500
#define _WIN32_DCOM 
#include <windows.h>
#include <iostream>
//#import "ComputeService.exe" no_namespace named_guids
#include "../OutCalculator/OutCalculator.h"
#include "../OutCalculator/OutCalculator_i.c"
using namespace std;
template< class T >
void show( T t )
{
cout << t << endl;
}
void test_dcom1()
{
HRESULT hr;
hr = CoInitializeSecurity( NULL, 
   -1, 
   NULL, 
   NULL,
   RPC_C_AUTHN_LEVEL_NONE, 
   RPC_C_IMP_LEVEL_IDENTIFY, 
   NULL, 
   EOAC_NONE, 
   NULL );
if( !SUCCEEDED( hr ) )
{
show( "init right failed!" );
}
COSERVERINFO si;
MULTI_QI     qi;
ZeroMemory( &si, sizeof( si ) );
ZeroMemory( &qi, sizeof( qi ) );
si.pwszName = L"192.168.4.143";//自己機器的IP
si.pAuthInfo = NULL;
qi.pIID = &IID_Icalmath;
qi.pItf = NULL;
hr = CoCreateInstanceEx(CLSID_calmath, NULL, CLSCTX_REMOTE_SERVER, &si, 1, &qi);
if( FAILED( hr ) )
{
cout << "can not create myobject : " << GetLastError() << endl;
return;
}
if (FAILED(qi.hr))
{
cout << "can not create myobject : " << GetLastError() << endl;
return;
}
////////////////////////////////////
Icalmath * pT = NULL;
qi.pItf->QueryInterface( &pT );
qi.pItf->Release();
int data = 0;
long result=0.0;
int flag;
int a,b;
printf("請選擇:1.加;2.減;3.乘;4.除;5.判斷素數(注:1表示素數;0表示非素數);0.退出\n");
scanf("%d",&flag);
while(flag!=0){
switch(flag){
    case 1:    printf("請輸入要相加的兩個數字:") ;
   scanf("%d%d",&a,&b);
           pT->add(a,b,&data);
   printf("計算結果為:");
           show( data );
   break;
    case 2:    printf("請輸入要相減的兩個數字:") ;
   scanf("%d%d",&a,&b);
           pT->sub(a,b,&data);
   printf("計算結果為:");
           show( data );
   break;
    case 3:   printf("請輸入要相乘的兩個數字:") ;
   scanf("%d%d",&a,&b);
           pT->multiply(a,b,&result);
   printf("計算結果為:");
           show( result );
   break;
case 4:    printf("請輸入要相除的兩個數字:") ;
   scanf("%d%d",&a,&b);
           pT->divide(a,b,&result);
   printf("計算結果為:");
           show( result );
   break;
case 5:    printf("請輸入要進行判斷的數字:") ;
   scanf("%d",&a);
           pT->sushu(a,&data);
   printf("判斷結果為:");
           show( data );
   break;
     
case 0:break;
default:break;
}
printf("請選擇:1.加;2.減;3.乘;4.除;5.判斷素數(注:1表示素數;0表示非素數);0.退出\n");
scanf("%d",&flag);
}
pT->Release(); 
}
void main()
{
CoInitialize( NULL );
test_dcom1();
CoUninitialize();
}


進行編譯連線,執行,如下所示: