感谢焦龙同学的耐心讲解~~~~
1. 如何搭建DCOM编程、运行环境
N台机器的用户名和密码必须相同。最好是用Administrator
进入VC++6.0,打开HelloDcom.dsw,组建工具栏调出来。
程序全编译一遍
Server -> 组建->全部组建
PSAddSub -> 工具-> Register Control
至此配置完成
看两台机器是否可以进行DCOM访问:
网上邻居:
看访问125.223.8.122是否成功,进入工作组,输入如下:
出现如下就证明可以进行通信了。
本机IP = 125.223.8.113。测试的时候这里添加自己的IP号就行。如果想连接对方(125.223.8.122),就填对方的IP号即可。这只是一个例子,测试程序而已。以后讲到的IP访问将不是这个样子。
运行
2. 如何新建立一个DCOM工程。
Parallel Mesh Search=PMS,原地盖高楼。
之前那些事对于例子程序的调通,下面是如何新建立一个DCOM工程。
DCOM工程大概分为3个子工程:Server端、代理DLL、Client端。这3部分分别要建立3个工程。
2.1 建立Server端
先建立一个空白的工作区
再新建Server端工程PMS
组件接口函数的定义
HRESULT Para_MeshSearch( [in] long length,
[in,size_is(length)] long* raw_Array,
[out,size_is(length)] long* back_Array );
组件接口函数的声明
在public:里面加入一句话STDMETHOD(Para_MeshSearch)( long length, long* raw_Array, long* back_Array);
组件接口函数的实现
向此文件中添加:
STDMETHODIMP CPMSCom::Para_MeshSearch(long length, long* rawArray, long* outArray)
{
//函数功能
return NOERROR;
}
注意,在编写PMSCom.cpp也就是Server端代码的时候,接口函数中数组rawArray是一个long*类型,在接口函数中不用重新给这个rawArray分配空间。因为调用这个函数的时候实参是一个具体数组。
组件注册:一般地,编译完成服务器自动注册
选中PMSCom.cpp,再编译!
2.2 建立代理/存根DLL
这2.2节都是在PSPMS工程中的操作。再新建一个工程PSPMS
向PSPMS.def中添加如下内容:
LIBRARY PSPMS
EXPORTS
DllGetClassObject PRIVATE
DllCanUnloadNow PRIVATE
DllRegisterServer PRIVATE
DllUnregisterServer PRIVATE
GetProxyDllInfo PRIVATE
把PMS.idl生成的如下4个文件加入到工程中。
方法如下:
在如下位置加入 ,REGISTER_PROXY_DLL, _WIN32_DCOM
在如下位置加入 rpcndr.lib rpcns4.lib rpcrt4.lib
记得rpcndr.lib前面加个空格
编译,连接
注册dll:
2.3 建立客户程序
新建一个工程
PMS_Client.cpp中的#include "stdafx.h"删了它就可以了。。。否则有出不尽的编译、链接错误。
客户端PMS_Client工程必须包含PMS.h和PMS_i.c文件。方法上面都说过了。
注意:在客户端,无论编写debug还是release程序,project\setting\ c/c++中的code generation下的Use run-time library应选DEBUG Multithreaded DLL。下图所示:
3. 代码填充
3.1 PMS_Client.cpp的框架
可能用到的头文件
#include
#include
#include
#include
#include
#include
#include "../PMS/PMS.h" //这个一定用得上
#define MAX_SERVER_NUM 20 //服务器的最大个数
using namespace std;
struct PMS_Range
{
long *Trans_Array;
long *Back_Array;
long length;
int pid;
};
定义struct PMS_Range,这个东东任务分配用的。变量一般要定义为结构体数组,目的是传给好几个处理机,每一个结构体数组元素就是一个处理机的任务。添加到多线程调用的参数中,跟多线程一起传到处理机那边。
struct PQS_Time
{
time_t start;
time_t end;
};
PQS_Time ptime; //处理机共同的时间,总体的时间
全局变量:
int ser_num; //用户设定服务器个数
long element_num; //数据量,数量级,保证很大的
HANDLE PMS_ThreadM[MAX_SERVER_NUM]; //客户端线程,保证每个线程对应一个服务器
char Processor[MAX_SERVER_NUM][15]; //服务器IP地址
PMS_Range range[MAX_SERVER_NUM]; //任务划分范围
从servername.txt中读取IP地址列表。文件里面每一行是一个IP地址。
void ReadProcessorList()
{
int i;
ifstream infile("servername.txt", ios::in);
for(i=0;i>Processor[i];
infile.close();
}
多线程运行函数。一个线程运行一个这样的run函数。
DWORD WINAPI run(LPvoid pRange)
{
PMS_Range* myrange = (PMS_Range*)pRange;
//通信部分
return 0;
}
ptime.start=GetTickCount(); //开始计算时间
ptime.end=GetTickCount(); //停止计算时间
printf("\n本次运算使用了%d台处理机,运行时间为:%dms\n", ser_num, ptime.end-ptime.start);
3.2 通信部分
红色的字为个性化信息,表示使用
模板
个人简介word模板免费下载关于员工迟到处罚通告模板康奈尔office模板下载康奈尔 笔记本 模板 下载软件方案模板免费下载
后需要根据自己工程的命名、函数调用改动的地方
//绿色的字,你懂的,不解释。。。
HRESULT hResult;
hResult = CoInitialize(NULL); //初始化COM库
if (FAILED(hResult))
{
return 0;
}
IClassFactory *pClf;
IUnknown *pIUnknown;
wchar_t ip[42] ; //放弃使用CString类型,用wchar_t好
int len = strlen(Processor[myrange->pid]);
mbstowcs(ip, Processor[myrange->pid], len); //转换单字符串为宽字符串
ip[len] = 0 ; //设置字符串结尾
COSERVERINFO ServerInfo = { 0, ip, NULL, 0 }; //获取服务器信息
hResult=CoGetClassObject( CLSID_PMSCom,
CLSCTX_SERVER,
&ServerInfo,
IID_IClassFactory,
(void**)&pClf); //创建类厂
printf("\n线程%d正在连接服务器%s",myrange->pid,Processor[myrange->pid]);
if (FAILED(hResult))
{
printf("\n连接服务器%s失败",Processor[myrange->pid]);
return 0;
}
hResult = pClf->CreateInstance( NULL,
IID_IUnknown,
(void**) &pIUnknown); //创建组件对象
if (FAILED(hResult))
{
printf("\n创建组件对象失败[%d]",myrange->pid);
pClf->Release();
return 0;
}
pClf->Release(); //释放类厂
IPMSCom *pIMeshSearch;
hResult = pIUnknown->QueryInterface(IID_IPMSCom, (void**) &pIMeshSearch);//查询接口
if (FAILED(hResult))
{
pIUnknown->Release();
return 0;
}
//调用接口函数
pIMeshSearch->Para_MeshSearch( myrange->length,
myrange->Trans_Array,
myrange->Back_Array );
pIMeshSearch->Release();
pIUnknown->Release();
pIUnknown = NULL;
CoUninitialize(); //释放COM库
printf("\n线程[%d]结束.",myrange->pid);
3.3 多线程
在做并行计算的时候,需要几台处理机同时完成多个任务,这时,Client程序要建立N个线程,这N个线程将与N个处理机进行通信,将划分好的任务传给它们。每一个线程,都执行DWORD WINAPI run(LPVOID pRange)函数,在这个函数里面建立与处理机的链接,并且调用远程处理机上的接口函数,将任务传过去。等远程处理机做好以后,从[out]参数又传回数据。最后,Client将N个线程的传回数据加以处理。