青青草原综合久久大伊人导航_色综合久久天天综合_日日噜噜夜夜狠狠久久丁香五月_热久久这里只有精品

隨筆 - 60, 文章 - 0, 評(píng)論 - 197, 引用 - 0
數(shù)據(jù)加載中……

Win32 RPC 編程(一)

我們從一個(gè)簡(jiǎn)單的 RPC “Hello, world!”的例子開(kāi)始。
參考資料:MSDN: Win32 and COM Development -> Networking -> Network Protocols -> Remote Procedure Calls (RPC)


第1步:編寫(xiě) IDL(Interface Description Language,接口描述語(yǔ)言)文件
-------------------------------------------------------------------------
IDL 是一個(gè)通用的工業(yè)標(biāo)準(zhǔn)語(yǔ)言,大家應(yīng)該不陌生,因?yàn)?COM 里面也是用它來(lái)描述接口的。
Hello.idl:

[
     uuid("4556509F-618A-46CF-AB3D-ED736ED66477"),   // 唯一的UUID,用 GUIDGen 生成
     version(1.0)
]

interface HelloWorld 
{
     // 我們定義的方法
     void Hello([in,string]const char * psz);
     void Shutdown(void); 
}


一個(gè)可選的文件是應(yīng)用程序配置文件(.acf),它的作用是對(duì) RPC 接口進(jìn)行配置,例如下面的 Hello.acf 文件:
Hello.acf:


     implicit_handle(handle_t    HelloWorld_Binding) 


interface HelloWorld
{

}

上面定義了 implicit_handle,這樣客戶(hù)端將綁定句柄 HelloWorld_Binding 了,后面的客戶(hù)端代碼中我們會(huì)看到。


編譯 IDL 文件:
>midl Hello.idl
Microsoft (R) 32b/64b MIDL Compiler Version 6.00.0366
Copyright (c) Microsoft Corporation 1991-2002. All rights reserved.
Processing .\Hello.idl
Hello.idl
Processing .\Hello.acf
Hello.acf

 
我們可以看到自動(dòng)生成了 Hello.h, Hello_s.c, Hello_c.c 文件,這些叫做 rpc stub 程序,不過(guò)我們可以不管這個(gè)概念,
我們只需要知道 Hello.h 里面定義了一個(gè)

extern RPC_IF_HANDLE HelloWorld_v1_0_s_ifspec;

這個(gè) RPC_IF_HANDLE 將在后面用到。

 
第2步:編寫(xiě)服務(wù)端程序
-------------------------------------------------------------------------
第1步中我們已經(jīng)約定了調(diào)用的接口,那么現(xiàn)在我們開(kāi)始實(shí)現(xiàn)其服務(wù)端。代碼如下:
server.c

#include <stdlib.h>
#include <stdio.h>
#include "Hello.h"     // 引用MIDL 生成的頭文件

/**
 * 這是我們?cè)贗DL 中定義的接口方法
 * 需要注意一點(diǎn),IDL 里面的聲明是:void Hello([in,string]const char * psz);
 * 但是這里變成了const unsigned char *,為什么呢?
 * 參見(jiàn)MSDN 中的MIDL Command-Line Reference -> /char Switch
 * 默認(rèn)的編譯選項(xiàng),對(duì) IDL 中的char 按照unsigned char 處理
 */

void Hello(const unsigned char * psz)
{
     printf("%s\n", psz);
}

 
/** 這也是我們?cè)贗DL 中定義的接口方法,提供關(guān)閉server 的機(jī)制*/
void Shutdown(void)
{
     // 下面的操作將導(dǎo)致 RpcServerListen() 退出
     RpcMgmtStopServerListening(NULL);
     RpcServerUnregisterIf(NULL, NULL, FALSE);
}

int main(int argc,char * argv[])
{
     // 用Named Pipe 作為RPC 的通道,這樣EndPoint 參數(shù)就是Named Pipe 的名字
     // 按照Named Pipe 的命名規(guī)范,\pipe\pipename,其中pipename 可以是除了\
     // 之外的任意字符,那么這里用一個(gè)GUID 串來(lái)命名,可以保證不會(huì)重復(fù)
     RpcServerUseProtseqEp((unsigned char *)"ncacn_np", 20, (unsigned char *)"\\pipe\\{8dd50205-3108-498f-96e8-dbc4ec074cf9}", NULL);   

     // 注冊(cè)接口,HelloWorld_v1_0_s_ifspec 是在MIDL 生成的Hello.h 中定義的
     RpcServerRegisterIf(HelloWorld_v1_0_s_ifspec, NULL, NULL);
   
     // 開(kāi)始監(jiān)聽(tīng),本函數(shù)將一直阻塞
     RpcServerListen(1,20,FALSE);
     return 0;
}

// 下面的函數(shù)是為了滿(mǎn)足鏈接需要而寫(xiě)的,沒(méi)有的話(huà)會(huì)出現(xiàn)鏈接錯(cuò)誤
void __RPC_FAR* __RPC_USER midl_user_allocate(size_t len)
{
     return(malloc(len));
}

void __RPC_USER midl_user_free(void __RPC_FAR *ptr)
{
     free(ptr);
}

 

編譯:
>cl /D_WIN32_WINNT=0x500 server.c Hello_s.c rpcrt4.lib
用于 80x86 的 Microsoft (R) 32 位 C/C++ 優(yōu)化編譯器 14.00.50727.42 版
版權(quán)所有(C) Microsoft Corporation。保留所有權(quán)利。

server.c
Hello_s.c
正在生成代碼...
Microsoft (R) Incremental Linker Version 8.00.50727.42
Copyright (C) Microsoft Corporation.  All rights reserved.

/out:server.exe
server.obj
Hello_s.obj
rpcrt4.lib

編譯時(shí)為什么要指定 _WIN32_WINNT=0x500 呢?因?yàn)槿绻麤](méi)有的話(huà)會(huì)報(bào)告下面的錯(cuò)誤:
Hello_s.c(88) : fatal error C1189: #error :  You need a Windows 2000 or later to
run this stub because it uses these features:

 
第3步:編寫(xiě)客戶(hù)端程序
-------------------------------------------------------------------------
客戶(hù)端的代碼:
client.c

#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#include "Hello.h"     // 引用MIDL 生成的頭文件

int main(int argc, char * argv[])
{
     unsigned char * pszStringBinding = NULL;
     if ( argc != 2 )
     {
         printf("Usage:%s <Hello Text>\n", argv[0]);
         return 1;
     }   

     // 用Named Pipe 作為RPC 的通道。參見(jiàn)server.c 中的RpcServerUseProtseqEp() 部分
     // 第3 個(gè)參數(shù)NetworkAddr 如果取NULL,那么就是連接本機(jī)服務(wù)
     // 否則要取\\\\servername 這樣的格式,例如你的計(jì)算機(jī)名為jack,那么就是\\jack
     RpcStringBindingCompose( NULL, (unsigned char*)"ncacn_np", /*(unsigned char*)"\\\\servername"*/ NULL, (unsigned char*)"\\pipe\\{8dd50205-3108-498f-96e8-dbc4ec074cf9}", NULL, &pszStringBinding );

     // 綁定接口,這里要和 Hello.acf 的配置一致,那么就是HelloWorld_Binding
     RpcBindingFromStringBinding(pszStringBinding, & HelloWorld_Binding );   

     // 下面是調(diào)用服務(wù)端的函數(shù)了
     RpcTryExcept
     {
         if ( _stricmp(argv[1], "SHUTDOWN") == 0 )
         {
              Shutdown();
         }
         else
         {
              Hello((unsigned char*)argv[1]);
         }
     }
     RpcExcept(1)
     {
         printf( "RPC Exception %d\n", RpcExceptionCode() );
     }
     RpcEndExcept

 
     // 釋放資源
     RpcStringFree(&pszStringBinding);
     RpcBindingFree(&HelloWorld_Binding);
     return 0;
}

 
// 下面的函數(shù)是為了滿(mǎn)足鏈接需要而寫(xiě)的,沒(méi)有的話(huà)會(huì)出現(xiàn)鏈接錯(cuò)誤
void __RPC_FAR* __RPC_USER midl_user_allocate(size_t len)
{
     return(malloc(len));
}

void __RPC_USER midl_user_free(void __RPC_FAR *ptr)
{
     free(ptr);
}

 

編譯:
>cl /D_WIN32_WINNT=0x500 client.c Hello_c.c rpcrt4.lib
用于 80x86 的 Microsoft (R) 32 位 C/C++ 優(yōu)化編譯器 14.00.50727.42 版
版權(quán)所有(C) Microsoft Corporation。保留所有權(quán)利。

client.c
Hello_c.c
正在生成代碼...
Microsoft (R) Incremental Linker Version 8.00.50727.42
Copyright (C) Microsoft Corporation.  All rights reserved.

/out:client.exe
client.obj
Hello_c.obj
rpcrt4.lib

 

第4步:測(cè)試:
-------------------------------------------------------------------------
運(yùn)行 server.exe,將彈出一個(gè) console 窗口,等待客戶(hù)端調(diào)用。
運(yùn)行客戶(hù)端 client.exe:

>client hello
可以看到 server.exe 的 console 窗口出現(xiàn) hello 的字符串。


>client shutdown
server.exe 退出。

示例下載
 

posted on 2008-04-28 18:50 Normandy 閱讀(23110) 評(píng)論(16)  編輯 收藏 引用 所屬分類(lèi): Networking

評(píng)論

# re: Win32 RPC 編程(一)  回復(fù)  更多評(píng)論   

你好,你的Win32 RPC 編程(一)讓我對(duì)Windows RPC編程有了一個(gè)很形象地認(rèn)識(shí),非常感謝。不過(guò)我在用你的代碼做實(shí)驗(yàn)時(shí)發(fā)現(xiàn)編譯有些問(wèn)題,之今不知道為什么。還望賜教。

我用2005新建了一個(gè)c++ Console Application,然后按照你的順序,依次新建了Hello.idl和Hello.acf文件,編譯后,的確看到生成出來(lái)的Hello_c.c,Hello_h.h和Hello_s.c,但在Solution Explorer中看不到這些生成出來(lái)的文件。接著我復(fù)制完服務(wù)端程序后編譯后,出現(xiàn)下列錯(cuò)誤:
1>RPCServer.obj : error LNK2019: unresolved external symbol __imp__RpcServerUnregisterIf@12 referenced in function _Shutdown
1>RPCServer.obj : error LNK2019: unresolved external symbol __imp__RpcMgmtStopServerListening@4 referenced in function _Shutdown
1>RPCServer.obj : error LNK2019: unresolved external symbol __imp__RpcServerListen@12 referenced in function _wmain
1>RPCServer.obj : error LNK2019: unresolved external symbol __imp__RpcServerRegisterIf@12 referenced in function _wmain
1>RPCServer.obj : error LNK2001: unresolved external symbol _HelloWorld_v1_0_s_ifspec
1>RPCServer.obj : error LNK2019: unresolved external symbol __imp__RpcServerUseProtseqEpW@16 referenced in function _wmain

如果我將那幾個(gè)生成出來(lái)的文件手動(dòng)加入到Solution Explore中后,編譯后報(bào)下列錯(cuò)誤:

1>Hello_s.c
1>c:\zhongwei\rpc\rpcserver\rpcserver\hello_s.c(226) : fatal error C1010: unexpected end of file while looking for precompiled header. Did you forget to add '#include "stdafx.h"' to your source?
1>Hello_c.c
1>c:\zhongwei\rpc\rpcserver\rpcserver\hello_c.c(225) : fatal error C1010: unexpected end of file while looking for precompiled header. Did you forget to add '#include "stdafx.h"' to your source?

你能知道是什么原因造成的么?
2008-10-19 13:56 | 金中偉

# re: Win32 RPC 編程(一)  回復(fù)  更多評(píng)論   

我的EMAIL:juniorzhong@gmail.com
MSN:junior_zhong@tom.com

期待你的指點(diǎn),謝謝!
2008-10-19 14:08 | 金中偉

# re: Win32 RPC 編程(一)  回復(fù)  更多評(píng)論   

@金中偉
其實(shí)沒(méi)有這么復(fù)雜,我是通過(guò) Makefile 編譯的, 沒(méi)有用 IDE。你打開(kāi) Visual Studio 2005 Command Prompt 或 Visual Studio 2008 Command Prompt ,然后進(jìn)到源碼目錄下 敲一個(gè) nmake 命令, 所有的都會(huì)為你自動(dòng)生成。細(xì)節(jié)可查看源碼目錄下的 Makefile 文件。
2008-10-20 10:09 | Normandy

# re: Win32 RPC 編程(一)  回復(fù)  更多評(píng)論   

@金中偉
你出錯(cuò)的原因貌似是有些函數(shù)庫(kù)沒(méi)有添加到引用中,所以編譯時(shí)有無(wú)法解析的標(biāo)志錯(cuò)誤?;蛘吒こ叹幋a有關(guān),自己察看下吧
2009-08-03 18:17 | qb

# re: Win32 RPC 編程(一)  回復(fù)  更多評(píng)論   

你的問(wèn)題是沒(méi)有添加RPC Runtime Library,你可以在工程屬性的'連接器'下的輸入 添加'附加依賴(lài)項(xiàng)' Rpcrt4.lib,或者在你的CPP文件開(kāi)頭添加如下語(yǔ)句
#pragma comment(lib, "Rpcrt4.lib")
2009-08-24 23:15 | Quincy, Hu

# re: Win32 RPC 編程(一)  回復(fù)  更多評(píng)論   

RPC 學(xué)好了,大有用處。
2009-10-14 21:49 | jc_ontheroad

# re: Win32 RPC 編程(一)  回復(fù)  更多評(píng)論   

問(wèn)下大家,在windows下編譯器cl.exe 用/I來(lái)說(shuō)明頭文件的路徑,用什么參數(shù)來(lái)說(shuō)明庫(kù)文件的路徑啊?
2011-04-27 08:03 | liweihua

# re: Win32 RPC 編程(一)  回復(fù)  更多評(píng)論   

@liweihua
/LIBPATH:"X:\xxx\xxx"
2011-04-27 09:28 | 溪流

# re: Win32 RPC 編程(一)  回復(fù)  更多評(píng)論   

windows下有沒(méi)有像RPCGEN這樣的工具啊?
2011-08-24 16:38 | tal

# re: Win32 RPC 編程(一)  回復(fù)  更多評(píng)論   

呵呵,樓主,感謝你的文章啊。
我也喜歡用命令行編譯程序。呵呵
2012-05-25 15:16 | 憑凡

# re: Win32 RPC 編程(一)  回復(fù)  更多評(píng)論   

我在2010編譯的。結(jié)果是1714結(jié)果,
服務(wù)器起不來(lái)
2012-09-03 14:23 | 董香升

# re: Win32 RPC 編程(一)  回復(fù)  更多評(píng)論   

我把程序改成相應(yīng)的wchar_t的unicode版本??墒莝erver.cpp中RpcServerUseProtseqEp返回1703號(hào)錯(cuò)誤。找不到愿意,希望指點(diǎn)一下。我在開(kāi)頭#define UNICODE了。
2012-09-04 11:31 |

# re: Win32 RPC 編程(一)  回復(fù)  更多評(píng)論   

我把程序改成相應(yīng)的wchar_t的unicode版本。可是server.cpp中RpcServerUseProtseqEp返回1703號(hào)錯(cuò)誤。找不到愿意,希望指點(diǎn)一下。我在開(kāi)頭#define UNICODE了。
2012-09-04 11:32 | 董香升

# re: Win32 RPC 編程(一)  回復(fù)  更多評(píng)論   

請(qǐng)教原因和解決方法:
網(wǎng)上獲取RPC實(shí)例,比如http://blog.163.com/junior_zhong/blog/static/27871180200891810561138/
在main()中的:
status = RpcServerUseProtseqEp(
reinterpret_cast <unsigned char*>("ncacn_np"),
nMaxCalls,
reinterpret_cast <unsigned char*>("//pipe//{a5194558-21a6-4978-9610-2072fcf1dc6e}"),
NULL );

編譯時(shí)出現(xiàn)錯(cuò)誤:
error C2664: 'RpcServerUseProtseqEpW' : cannot convert parameter 1 from 'unsigned char *' to 'RPC_WSTR'
按照網(wǎng)上方法,reinterpret_cast <unsigned char*>可以解決兩個(gè)字符串問(wèn)題,但是不能搞定最后一個(gè)參數(shù)NULL一直報(bào)錯(cuò)C2664。
2012-09-06 14:34 | iHyy

# re: Win32 RPC 編程(一)  回復(fù)  更多評(píng)論   

@董香升
請(qǐng)問(wèn)后來(lái)怎么解決的?。?
2015-07-13 15:58 | 范范

# re: Win32 RPC 編程(一)  回復(fù)  更多評(píng)論   

如果你沒(méi)有使用Makefile編譯而是采用vs的屬性中配置來(lái)編譯,server.cpp中RpcServerUseProtseqEp返回1703號(hào)錯(cuò)誤, 或是RpcServerListen報(bào)錯(cuò)。請(qǐng)?jiān)趯傩皂?yè)->常規(guī)->字符集中選擇未設(shè)置,也就是disable UNICODE
2016-02-17 13:55 | zhang_luo@qq.com

只有注冊(cè)用戶(hù)登錄后才能發(fā)表評(píng)論。
網(wǎng)站導(dǎo)航: 博客園   IT新聞   BlogJava   博問(wèn)   Chat2DB   管理


青青草原综合久久大伊人导航_色综合久久天天综合_日日噜噜夜夜狠狠久久丁香五月_热久久这里只有精品
  • <ins id="pjuwb"></ins>
    <blockquote id="pjuwb"><pre id="pjuwb"></pre></blockquote>
    <noscript id="pjuwb"></noscript>
          <sup id="pjuwb"><pre id="pjuwb"></pre></sup>
            <dd id="pjuwb"></dd>
            <abbr id="pjuwb"></abbr>
            欧美顶级少妇做爰| 久久人人爽人人| 欧美一区二区在线播放| 国产精品萝li| 欧美专区日韩视频| 欧美成人一区二区三区片免费| 亚洲区中文字幕| 欧美日韩中文精品| 欧美一级在线播放| 欧美国产日本高清在线| 亚洲一线二线三线久久久| 国产一区二区高清| 欧美精品免费在线观看| 亚洲一区二区三区在线观看视频| 久久久亚洲高清| 亚洲精品一区二区在线观看| 国产精品久久午夜| 久久午夜激情| 亚洲一区二区三区午夜| 欧美刺激性大交免费视频| 亚洲午夜精品久久| 伊人久久婷婷| 国产精品久久久久久久久久三级| 久久―日本道色综合久久| 日韩一区二区福利| 免费在线观看成人av| 亚洲一区二区毛片| 亚洲国产导航| 国产欧美日韩免费| 欧美日韩国产区一| 久久先锋影音av| 亚洲欧美国内爽妇网| 亚洲国产精品va在线看黑人动漫| 午夜精品免费视频| 亚洲毛片播放| 国产最新精品精品你懂的| 欧美日韩一区高清| 欧美本精品男人aⅴ天堂| 欧美亚洲系列| 一区二区欧美日韩视频| 欧美国产日韩视频| 久久久www成人免费无遮挡大片| 一区二区久久久久久| 极品少妇一区二区三区精品视频| 欧美视频在线观看免费| 嫩草影视亚洲| 久久美女性网| 久久福利资源站| 亚洲女优在线| 亚洲一区日韩在线| 99一区二区| 亚洲欧洲一二三| 亚洲第一网站免费视频| 欧美/亚洲一区| 免费在线看成人av| 久久久久久久综合狠狠综合| 欧美一区二区成人| 亚洲欧美日韩一区二区在线| 亚洲一区二区三区在线看| 亚洲日本中文字幕免费在线不卡| 在线日本成人| 在线观看视频日韩| 激情综合色综合久久| 国产亚洲欧美一区二区三区| 国产欧美亚洲视频| 国产精品视频免费观看| 国产精品美腿一区在线看| 国产精品videosex极品| 国产精品国产三级国产专区53 | 亚洲美洲欧洲综合国产一区| 一色屋精品视频在线观看网站| 国产一区二区三区免费不卡 | 欧美不卡在线视频| 免费观看成人| 欧美激情按摩| 91久久线看在观草草青青| 最新日韩精品| 日韩亚洲欧美一区| 亚洲视频一区二区| 亚洲中午字幕| 欧美在线免费视屏| 久久影音先锋| 欧美激情黄色片| 欧美日韩一区二区三区免费| 欧美日韩精品二区第二页| 久久精品国产999大香线蕉| 亚洲成人资源网| 亚洲高清视频的网址| 日韩亚洲欧美成人| 亚洲宅男天堂在线观看无病毒| 欧美在线观看视频一区二区三区| 久久久91精品国产一区二区三区 | 欧美一区二区| 久久米奇亚洲| 欧美精品七区| 国产精品视频福利| 在线观看日韩av电影| 亚洲精选大片| 午夜视频一区| 欧美顶级少妇做爰| 99综合在线| 久久精品首页| 欧美日韩三级视频| 国产欧美一区二区精品仙草咪| 伊人色综合久久天天五月婷| 99精品欧美| 久久久久久婷| 亚洲免费大片| 久久精品女人天堂| 欧美日韩免费在线观看| 国产一区二区三区免费观看| 亚洲乱码日产精品bd| 先锋a资源在线看亚洲| 欧美成人午夜免费视在线看片| 一区二区三区三区在线| 久久亚洲一区二区| 亚洲精一区二区三区| 国产精品国产一区二区 | 亚洲影视在线播放| 一区二区毛片| 久久躁日日躁aaaaxxxx| 噜噜噜噜噜久久久久久91| 欧美午夜一区二区福利视频| 影音先锋日韩资源| 亚洲在线观看免费| 亚洲电影免费观看高清完整版在线| av72成人在线| 男女激情久久| 黄色成人av在线| 欧美一区二区三区视频| 亚洲日本中文字幕| 欧美一站二站| 国产乱码精品一区二区三区五月婷| 99精品久久免费看蜜臀剧情介绍| 久久久精品五月天| 国内精品视频在线播放| 欧美体内谢she精2性欧美| 在线观看成人一级片| 久久av资源网站| 亚洲视频一区在线观看| 欧美成人第一页| 一区二区三区在线观看国产| 亚洲自拍偷拍视频| 日韩视频免费观看高清完整版| 免费不卡在线视频| 一区二区三区在线不卡| 久久av二区| 亚洲影视中文字幕| 国产精品毛片va一区二区三区 | 欧美激情小视频| 久久久久久黄| 黄色资源网久久资源365| 久久国产一二区| 篠田优中文在线播放第一区| 国产精品久久久久久影院8一贰佰| 中文国产成人精品| 日韩视频一区二区三区在线播放| 欧美精品三级| 一区二区三区视频在线看| 亚洲精品国产精品乱码不99 | 欧美国产一区二区三区激情无套| 怡红院精品视频| 欧美aa在线视频| 欧美成年人网| 一二美女精品欧洲| 在线亚洲一区二区| 国产麻豆综合| 久久久99爱| 久久久久综合一区二区三区| 亚洲二区在线| 亚洲经典在线| 欧美色欧美亚洲高清在线视频| 亚洲天堂视频在线观看| 亚洲午夜在线| 国模精品娜娜一二三区| 男女激情久久| 欧美激情国产高清| 亚洲专区一区| 欧美一区二区精品在线| 亚洲福利国产| 亚洲裸体在线观看| 国产精品毛片一区二区三区| 久久久久高清| 麻豆久久久9性大片| 99亚洲视频| 午夜精品视频网站| 亚洲国产成人精品女人久久久 | 久久久精品国产免费观看同学| 亚洲国产高清自拍| 亚洲伦理在线| 国内免费精品永久在线视频| 欧美激情片在线观看| 欧美色欧美亚洲高清在线视频| 久久av一区| 欧美国产精品中文字幕| 午夜宅男久久久| 欧美第一黄色网| 欧美亚洲综合久久| 男人插女人欧美| 欧美一区二区在线免费播放|