??xml version="1.0" encoding="utf-8" standalone="yes"?> 当然是可以的。具体参见:让C++代码与C#代码一L成一个单一的Assembly The last two Nuts and Bolts articles focused on database related topics. This month we'll change gears and focus on something different. The focus of this month's article will be .NET remoting. We'll discuss what is .NET Remoting, how it compares to DCOM and Web services, and go through an example. .NET Remoting is an enabler for application communication. It is a generic system for different applications to use to communicate with one another. .NET objects are exposed to remote processes, thus allowing interprocess communication. The applications can be located on the same computer, different computers on the same network, or even computers across separate networks. In the past interprocess communication between applications was handled through Distributed COM, or DCOM. DCOM works well and the performance is adequate when applications exist on computers of similar type on the same network. However, DCOM has its drawbacks in the Internet connected world. DCOM relies on a proprietary binary protocol that not all object models support, which hinders interoperability across platforms. In addition, have you tried to get DCOM to work through a firewall? DCOM wants to communicate over a range of ports that are typically blocked by firewalls. There are a ways to get it to work, but they either decrease the effectiveness of the firewall (why bother to even have the firewall if you open up a ton of ports on it), or require you to get a firewall that allows support for binary traffic over port 80. .NET Remoting eliminates the difficulties of DCOM by supporting different transport protocol formats and communication protocols. This allows .NET Remoting to be adaptable to the network environment in which it is being used. Unless you have been living in a cave, or are way behind in your reading, you have probably read something about Web services. When you read the description of .NET Remoting it may remind you a lot of what you're read about Web services. That is because Web services fall under the umbrella of .NET Remoting, but have a simplified programming model and are intended for a wide target audience. Web services involve allowing applications to exchange messages in a way that is platform, object model, and programming language independent. Web services are stateless and know nothing about the client that is making the request. The clients communicate by transferring messages back and forth in a specific format known as the Simple Object Access Protocol, or SOAP. (Want to get some funny looks in the hallway? Stand around in the hallway near the marketing department with your colleagues and discuss the benefits of using SOAP). The following list outlines some of the major differences between .NET Remoting and Web services that will help you to decide when to use one or the other: Remote objects are accessed through Channels. Channels physically transport the messages to and from remote objects. There are two existing channels TcpChannel and HttpChannel. Their names give away the protocols that they use. In addition, the TcpChannel or HttpChannel can be extended, or a new channel created if you determine the existing channels do not meet your needs. A remotable object is nothing more than an object that inherits from MarshalByRefObject. The following sample demonstrates a simple class to expose the omnipresent hello world. This object exposes a single method HelloWorld that will return a string. The only values that can be returned from methods are the classes in the .NET Framework that are serializable such as string and DataSet. In addition, if you need to return a user-defined object then the object needs to be marked as serializable. Create a new C# class library project. Add a class called SampleObject and put in the following code. Add a reference to System.Runtime.Remoting in the project, otherwise the TcpChannel will not be found. Compile the class to make sure you have everything correct. We need to create a server object that will act as a listener to accept remote object requests. For this example we will use the TCP/IP channel. We first create an instance of the channel and then register it for use by clients at a specific port. The service can be registered as WellKnownObjectMode.SingleCall, which results in a new instance of the object for each client, or as WellKnownObjectMode.Singleton, which results in one instance of the object used for all clients. It is not necessary to create the server listener if you are planning to use IIS. For obvious reasons, IIS only supports the use of the HttpChannel. Create a virtual directory for your application and then put code to register your service in the Application_Start event. For our example, we'll go ahead and create a server listener in case you don't have IIS. Since the service needs to be bound to an available port, for our example I chose 8080, which is a port that I know to be unused on my computer. You may need to choose a different port depending upon what ports you have available. To see a list of the used ports on your computer open a command prompt and issue the command "netstat --a". It may produce a long listing so make sure the command prompt buffer sizes are set to allow scrolling. Compile the class to make sure you have everything correct. Create a new C# console application project. Add a class called SampleServer and paste in the following code. Add a reference to System.Runtime.Remoting in the project, otherwise the TcpChannel will not be found. In addition, add a reference to the project containing the SampleObject, otherwise the code will not compile because it won't know how to find a reference to SampleObject. Now that we have our remotable object and a server object to listen for requests, let's create a client to use it. Our client will be very simple. It will connect to the server, create an instance of the object using the server, and then execute the HelloWorld method. Create a new C# console application project. Add a class called SampleClient and paste in the following code. Add a reference to System.Runtime.Remoting in the project, otherwise the TcpChannel will not be found. In addition, add a reference to the project containing the SampleObject, otherwise the code will not compile because it won't know how to find a reference to SampleObject. Compile the class to make sure you have everything correct. Once you have created the projects and successfully compiled each of them you are ready to try it out. Assuming you chose a free TCP/IP port for the service, start the server executable. After the server successfully starts it will result in a console window being displayed with the message "Press the enter key to exit". The server is listening so you are now ready to run the client. Executing the client should result in "Hello World!" being displayed in a separate console window. The client window will then close while the server remains open and available. If you have multiple computers available to you on a network you could execute the server on one machine and the client on another just to prove to yourself that it really is remoting. In order to run on separate machines you would need to change the reference to localhost in the sample client to point to the appropriate location. .NET Remoting is a powerful way to enable interprocess communication. It is more complicated to program against than Web services. You need to decide for yourself whether your standard architecture is to use .NET Remoting or Web services. The next column will be on the use of encryption in the .NET framework. We'll take a look at some of the encryption algorithms available in the framework and ways to use them. If you have a particular topic in mind please email me at mstrawmyer@crowechizek.com Mark Strawmyer, MCSD, MCSE (NT4/W2K), MCDBA is a Senior Architect of .NET applications for large and mid-size organizations. Mark is a technology leader with Crowe Chizek in Indianapolis, Indiana. He specializes in architecture, design and development of Microsoft-based solutions. You can reach Mark at mstrawmyer@crowechizek.com.
找了好几天了Q很多资源都下不?br>
今天好不Ҏ下了一个,但是香港版的Q且安装到选择盘符Ӟ键盘所有键都不能用,所以还是无法安?br>
谢谢各位大哥大姐帮帮忙,弟感激不尽Q?img src ="http://www.shnenglu.com/twzheng/aggbug/109710.html" width = "1" height = "1" />
]]>
本文作者:sodme
本文出处Q?font style="COLOR: #000000" color=#0000ff>http://blog.csdn.net/sodme
声明Q本文可以不l作者同意Q意{载、复制、传播,但Q何对本文的引用均M留本文的作者、出处及本行声明信息Q谢谢!
完成端口模型Q针对于WINq_的其它异步网l模型而言Q最大的好处Q除了性能斚w的卓外Q还在于完成端口在传递网l事件的通知Ӟ可以一q传递与此事件相关的应用层数据。这个应用层数据Q体现在两个斚wQ一是单句柄数据Q二是单IO数据?br>
GetQueuedCompletionStatus函数的原型如下:
WINBASEAPI
BOOL
WINAPI
GetQueuedCompletionStatus(
IN HANDLE CompletionPort,
OUT LPDWORD lpNumberOfBytesTransferred,
OUT PULONG_PTR lpCompletionKey,
OUT LPOVERLAPPED *lpOverlapped,
IN DWORD dwMilliseconds
);
其中Q我们把W三个参数lpCompletionKeyUCؓ完成键,由它传递的数据UCؓ单句柄数据。我们把W四个参数lpOverlappedUCؓ重叠l构体,由它传递的数据UCؓ单IO数据?br>
以字面的意思来理解QlpCompletionKey内包容的东西应该是与各个socket一一对应的,而lpOverlapped是与每一ơ的wsarecv或wsasend操作一一对应的?br>
在网l模型的常见设计中,当一个客Lq接到服务器后,服务器会通过accept或AcceptEx创徏一个socketQ而应用层Z保存与此socket相关的其它信息(比如Q该socket所对应的sockaddr_inl构体数据,该结构体内含客户端IP{信息,以及Z于客L的逻辑包整理而准备的数据整理~冲区等Q,往往需要创Z个与该socket一一对应的客L底层通信对象Q这个对象可以负责保存仅在网l层需要处理的数据成员和方法,然后我们需要将此客L底层通信对象攑օ一个类glist或map的容器中Q待到需要用的时候,使用容器的查扄法根据socket值找到它所对应的对象然后进行我们所需要的操作?br>
让h非常高兴的是Q完成端?#8220;体脓入微”Q它已经帮我们在每次的完成事仉知ӞE带着把该socket所对应的底层通信对象的指针送给了我们,q个指针是lpCompletionKey。也是_当我们从GetQueuedCompletionStatus函数取得一个数据接收完成的通知Q需要将此次收到的数据放到该socket所对应的通信对象整理~冲区内Ҏ据进行整理时Q我们已l不需要去执行list或map{的查找法Q而是可以直接定位q个对象了,当客Lq接量很大时Q频J查表还是很影响效率的。哇哦,太帅了,不是吗?呵呵?br>
Z以上的认识,我们的lpCompletionKey对象可以设计如下Q?br> typedef struct PER_HANDLE_DATA
{
SOCKET socket; //本结构体对应的socket?br> sockaddr_in addr; //用于存放客户端IP{信?br> char DataBuf[ 2*MAX_BUFFER_SIZE ]; //整理~冲?用于存放每次整理时的数据
}
PER_HANDLE_DATA与socket的绑定,通过CreateIOCompletionPort完成Q将该结构体地址作ؓ该函数的W三个参C入即可。而PER_HANDLE_DATAl构体中addr成员Q是在accept执行成功后进行赋值的。DataBuf则可以在每次WSARecv操作完成Q需要整理缓冲区数据时用?br>
下面我们再来看看完成端口的收、发操作中所使用到的重叠l构体OVERLAPPED?br>
关于重叠IO的知识,误行GOOGLE相关资料。简单地_OVERLAPPED是应用层与核心层交互׃n的数据单元,如果要执行一个重叠IO操作Q必d有OVERLAPPEDl构。在完成端口中,它允许应用层对OVERLAPPEDl构q行扩展和自定义Q允许应用层Ҏ自己的需要在OVERLAPPED的基上Ş成新的扩展OVERLAPPEDl构。一般地Q扩展的OVERLAPPEDl构中,要求攑֜W一个的数据成员是原OVERLAPPEDl构。我们可以Ş如以下方式定义自q扩展OVERLAPPEDl构Q?br> typedef struct PER_IO_DATA
{
OVERLAPPED ovl;
WSABUF buf;
char RecvDataBuf[ MAX_BUFFER_SIZE ]; //接收~冲?br> char SendDataBuf[ MAX_BUFFER_SIZE ]; //发送缓冲区
OpType opType; //操作cdQ发送、接收或关闭{?br> }
在执行WSASend和WSARecv操作Ӟ应用层会扩展OVERLAPPEDl构的地址传给核心Q核心完成相应的操作后,仍然通过原有的这个结构传递操作结果,比如“接收”操作完成后,RecvDataBuf里存放便是此ơ接收下来的数据?br>
Ҏ各自应用的不同,不同的完成端口设计者可能会设计Z同的PER_HANDLE_DATA
和PER_IO_DATAQ我q里l出的设计也只是针对自己的应用场合的Q不一定就适合你。但我想Q最主要的还是要搞明白PER_HANDLE_DATA和PER_IO_DATA两种l构体的含义、用途,以及调用程?br>
]]>
]]>
本文作者:sodme 本文出处Qhttp://blog.csdn.net/sodme
版权声明Q本文可以不l作者同意Q意{载,但{载时烦请保留文章开始前两行的版权、作者及出处信息?br>
QQ游戏于前几日l于H破了百万h同时在线的关口,向着更ؓq大的目标迈q,q让其它众多传统的棋牌休闲游戏^台黯然失Ԍ相比之下Q联众似乎已l根本不是QQ的对手,因ؓQQ除了q?00万的游戏在线人数外,它还拥有3亿多的注册量Q当然很多是重复注册的)以及QQ聊天软g900万的同时在线率,我们已经可以预见未来由QQ构徏h的强大棋牌休闲游戏帝国?br> 那么Q在技术上QQQ游戏到底是如何实现百万h同时在线q保持游戏高效率的呢Q?br> 事实上,针对于Q何单一的网l服务器E序Q其可承受的同时q接数目是有理论峰值的Q通过CQ+中对TSocket的定义类型:wordQ我们可以判定这个连接理论峰值是65535Q也是_你的单个服务器程序,最多可以承?万多的用户同时连接。但是,在实际应用中Q能辑ֈ一万h的同时连接ƈ能保证正常的数据交换已经是很不容易了Q通常q个值都?000?000之间Q据说QQ的单台服务器同时q接数目也就是在q个D间?br> 如果要实?000?000用户的单服务器同时在U,是不隄。在windows下,比较成熟的技术是采用IOCPQ-完成端口。与完成端口相关的资料在|上和CSDN论坛里有很多Q感兴趣的朋友可以自己搜索一下。只要运用得当,一个完成端口服务器是完全可以达?K?K的同时在UK的。但Q?Kq样的数值离百万q样的数值实在相差太大了Q所以,百万人的同时在线是单台服务器肯定无法实现的?br> 要实现百万h同时在线Q首先要实现一个比较完善的完成端口服务器模型,q个模型要求臛_可以承蝲2K?K的同时在U率Q当Ӟ如果你MONEY多,你也可以只开发出最多允?00人在U的服务器)。在构徏好了基本的完成端口服务器之后Q就是有x务器l的架构设计了。之所以说q是一个服务器l,是因为它l不仅仅只是一台服务器Q也l不仅仅是只有一U类型的服务器?br> 单地_实现百万人同时在U的服务器模型应该是Q登陆服务器Q大厅服务器Q房间服务器。当Ӟ也可以是其它的模型,但其基本的思想是一L。下面,我将逐一介绍q三cL务器的各自作用?br> 登陆服务器:一般情况下Q我们会向玩家开放若q个公开的登陆服务器Q就如QQ登陆时让你选择的从哪个QQ游戏服务器登陆一PQQ登陆时让玩家选择的六个服务器入口实际上就是登陆服务器。登陆服务器主要完成负蝲q的作用。详l点说就是,在登陆服务器的背后,有N个大厅服务器Q登陆服务器只是用于为当前的客户端连接选择其下一步应该连接到哪个大厅服务器,当登陆服务器为当前的客户端连接选择了一个合适的大厅服务器后Q客L开始根据登陆服务器提供的信息连接到相应的大厅上去,同时客户端断开与登陆服务器的连接,为其他玩家客Lq接登陆服务器腾出套接字资源。在设计登陆服务器时Q至应该有以下功能QN个大厅服务器的每一个大厅服务器都要与所有的登陆服务器保持连接,q实时地把本大厅服务器当前的同时在线人数通知l各个登陆服务器Q这其中包括Q用戯入时的同时在Uh数增加信息以及用户退出时的同时在Uh数减信息。这里的各个大厅服务器同时在UhC息就是登陆服务器为客L选择某个大厅让其登陆的依据。D例来_玩家A通过登陆服务?q接到登陆服务器Q登陆服务器开始ؓ当前玩家在众多的大厅服务器中Ҏ哪一个大厅服务器人数比较来选择一个大厅,同时把这个大厅的q接IP和端口发l客LQ客L收到q个IP和端口信息后Q根据这个信息连接到此大厅,同时Q客L断开与登陆服务器之间的连接,q便是用L陆过E中Q在登陆服务器这一块的处理程?br> 大厅服务器:大厅服务器,是普通玩家看不到的服务器Q它的连接IP和端口信息是登陆服务器通知l客L的。也是_在QQ游戏的本地文件中Q具体的大厅服务器连接IP和端口信息是没有保存的。大厅服务器的主要作用是向玩家发送游戏房间列表信息,q些信息包括Q每个游戏房间的cdQ名Uͼ在线人数Q连接地址以及其它如游戏帮助文件URL的信息。从界面上看的话Q大厅服务器是我们输入用户名和密码q校验通过后进入的游戏戉K列表界面。大厅服务器Q主要有以下功能Q一是向当前玩家q播各个游戏戉K在线人数信息Q二是提供游戏的版本以及下蝲地址信息Q三是提供各个游戏房间服务器的连接IP和端口信息;四是提供游戏帮助的URL信息Q五是提供其它游戏辅助功能。但在这众多的功能中Q有一Ҏ最为核心的Q即Qؓ玩家提供q入具体的游戏房间的通道Q让玩家利q入其欲q入的游戏房间。玩家根据各个游戏房间在Uh敎ͼ判定自己q入哪一个房_然后双击服务器列表中的某个游戏房间后玩家开始进入游戏房间服务器?br> 游戏戉K服务器:游戏戉K服务器,具体地说是?#8220;斗地?”Q?#8220;斗地?”q样的游戏房间。游戏房间服务器才是具体的负责执行游戏相关逻辑的服务器。这L游戏逻辑分ؓ两大c:一cL通用的游戏房间逻辑Q如Q进入房_d戉KQ进入桌子,d桌子以及在房间内说话{;W二cL游戏桌子逻辑Q这个就是各U不同类型游戏的主要区别之处了,比如斗地M的叫C或不叫地ȝ逻辑{,当然Q游戏桌子逻辑里也包括有通用的各个游戏里都存在的游戏逻辑Q比如在桌子内说话等。MQ游戏房间服务器才是真正负责执行游戏具体逻辑的服务器?br> q里提到的三cL务器Q我均采用的是完成端口模型,每个服务器最多连接数目是5000人,但是Q我在游戏房间服务器上作了逻辑层的限定Q最多只允许300人同时在Uѝ其他两个服务器仍然允许最?000人的同时在线。如果按照这Ll构来设计,那么要实现百万h的同时在U就应该是这P首先是大厅,1000000/5000Q?00。也是_臛_?00台大厅服务器Q但通常情况下,考虑到实际用时服务器的处理能力和负载情况,应该臛_准备250台左右的大厅服务器程序。另外,具体的各U类型的游戏戉K服务器需要多,pҎ当前玩各U类型游戏的玩家数目分别计算了,比如斗地L多是十万人同时在U,每台服务器最多允?00人同时在U,那么需要的斗地L务器数目应该不于Q?00000/300=333Q准备得充分一点,p准备350台斗C服务器?br> 除正常的玩家q接外,q要考虑刎ͼ
对于登陆服务器,会有250台大厅服务器q接到每个登陆服务器上,q是始终都要保持的连接;
而对于大厅服务器而言Q如果仅仅有斗地主这一cȝ服务器,p?50多个q接与各个大厅服务器始终保持着。所以从q一点看Q我的结构在某些斚wq存在着需要改q的地方Q但核心思想是:快地提供用L陆的速度Q尽可能方便地让玩家q入游戏中?
]]>
]]>
摘自Q?a class=headermaintitle id=Header1_HeaderTitle >沐枫筑 Q博客园博客Q?br>
转向.NET后,手头上往往仍有旧的模块要重用。也许这些模块是Delphi写的Q也许是C/C++写的Q或者是其它~程语言……Z能把它们UL?NET下,或者是?NET中调用,To be or not to be, that is a question?br> 在这里,我笔C几个在工作中遇到的几个场景。不q,q里不包括完全用C#来重写原来用C++~写的程序这U变态的需求。当你被要求做这U事的时候,请三思而后?#8230;…q简直是U非人的折磨?br>
您也使用托管C++吗? 如沐枫林
场景一Q在.NET中调用WindowsAPI或DLL?br>
q是比较普遍的需求。一般来_单的函数调用Q大可直接用C#/VB.NETQ经qDllImport属性包装出函数来调用。如Q?
[DllImport("KERNEL32.DLL", EntryPoint="MoveFileW", SetLastError=true,
CharSet=CharSet.Unicode, ExactSpelling=true,
CallingConvention=CallingConvention.StdCall)]
public static extern bool MoveFile(String src, String dst);
׃WindowsAPI用到的h实在是多Q因此有一个专门的wiki站点Q收集这斚w的资料:http://www.pinvoke.net/Q对于常用的函数甚至有完整的应用例子和帮助。当Ӟ如果你有相应的资料和例子Q你也可以A献你的力量,l其它h帮助?br>
场景?/strong>Q用托管C++包装现有的DLLQ供C#调用
当函数的参数或返回值比较复杂,或函数比较多的时候,q种Ҏ对与人来_实在是一个折。常常这些接口和定义p用掉几千行的代码Q而且q不能保证是正确的。这些错误往往在运行时才能昄出来Q甚x些错误会引v内存泄漏Q或其它更ؓ隐蔽的错误?br> 在这U情况下Q用C++/Managed代码来包装,成了最合理的选择。因为托C++代码可以直接引用原有的头文gQ直接调用非托管函数Q而不需要声明。这P既减了工作量,又避免引入错误。缺ҎQ这U方法会增加一个DLL?span style="COLOR: #ff0000">要注意的是托字W串和非托管字符串是有区别的Qƈ需要{换(特别要注意的Unicode字符串和多字节字W串的{换)?br>
仍以MoveFileZ吧,q样比较单:#include <windows.h>
#include <vcclr.h>
using namespace System;
namespace wrapper
{
public ref class ApiWrapper
{
public:
bool static MoveFile(String ^ lpExistingFileName, String ^ lpNewFileName )
{
pin_ptr<const wchar_t> src = PtrToStringChars(lpExistingFileName);
pin_ptr<const wchar_t> dst = PtrToStringChars(lpNewFileName);
return ::MoveFile(src, dst);
}
};
}
然后在C#中,引用上面代码生成的DLL文gQ就可以直接调用了:
wrapper.ApiWrapper.MoveFile(@"c:\debug.log", @"c:\debug.txt");
假如原有的代码是ZCOM的,那么太好了,VisualStudio{IDE会自动生成一个用于包装的dllQ供你调用。当然因Ҏ需要而手工编码的是另一回事?br>
场景?/strong>Q现有C++原代码,包装后供C#调用?br>
C++的原代码Q实际上可以直接~译成托代码。MFC也好ATL也好……q样看v来在.NET中最强大的编E语a是C++了:它不仅可以编写托程序,甚至可以标准C++的代码也~译成托程序!其实VC++最强大的地方不止如此,它还在于能够~写混合了托和非托的代码的程序!Q!q样最大的好处不仅可以关键代码直接编译成非托的代码Q还可以避免被反~译?br>
假设现有C++代码如下Q?br>
class UnmanagedClass
{
public:
LPCWSTR GetPropertyA()
{ return L"Hello!"; }
void MethodB( LPCWSTR )
{}
};
namespace wrapper
{
public ref class ManagedClass
{
public:
// Allocate the native object on the C++ Heap via a constructor
ManagedClass() : m_Impl( new UnmanagedClass )
{}
// Deallocate the native object on a destructor
~ManagedClass()
{
delete m_Impl;
}
protected:
// Deallocate the native object on the finalizer just in case no destructor is called
!ManagedClass()
{
delete m_Impl;
}
public:
property String ^ get_PropertyA
{
String ^ get()
{
return gcnew String( m_Impl->GetPropertyA());
}
}
void MethodB( String ^ theString )
{
pin_ptr<const WCHAR> str = PtrToStringChars(theString);
m_Impl->MethodB(str);
}
private:
UnmanagedClass * m_Impl;
};
}
然后Q改变编译选项?#8220;使用公共语言扩展 /clr”可以了。这P我们把代码编译成DLL文g可以供.NET其它语言调用了?br> 最后,C#中可以象如下的代码一栯用C++cMQ?
ManagedClass mc = new ManagedClass();
mc.MethoB("Hello");
string s = mc.get_PropertyA;
场景?/strong>Q如何在托管C++代码中合托和非托代?br>
很简单,只要?pragma unmanaged~译指示开始的E序Q一率编译成非托代码;要想恢复成托代码,只要使用#pragma managed可以了。如Q?br>
#pragma unmanaged
#include <iostream>
using namespace std;
template<typename T>
void f(T t)
{
cout << t << endl;
}
#pragma managed
using namespace System;
void m(String ^ s)
{
Console::WriteLine(s);
}
void main()
{
f("Hello");
m("World");
}
生成exe文g后,用反~译E序查看 f 函数Q?
[PreserveSig, MethodImpl(MethodImplOptions.Unmanaged, MethodCodeType=MethodCodeType.Native), SuppressUnmanagedCodeSecurity]
public static unsafe void modopt(CallConvCdecl) f<char const *>(sbyte modopt(IsSignUnspecifiedByte) modopt(IsConst)*);
看不到源码,而方法属性标CؓUnmanaged?br> 如果没有加上#pragma unmanagedQ反~译得到?f 函数为:
internal static unsafe void modopt(CallConvCdecl) f<char const *>(sbyte modopt(IsSignUnspecifiedByte) modopt(IsConst)* t)
{
std.basic_ostream<char,std::char_traits<char> >.<<(std.operator<<<struct std::char_traits<char> >(*((basic_ostream<char,std::char_traits<char> >* modopt(IsImplicitlyDereferenced)*) &__imp_std.cout), t), (basic_ostream<char,std::char_traits<char> >* modopt(IsImplicitlyDereferenced) modopt(CallConvCdecl) *(basic_ostream<char,std::char_traits<char> >* modopt(IsImplicitlyDereferenced))) __unep@?endl@std@@$$FYAAAV?$basic_ostream@DU?$char_traits@D@std@@@1@AAV21@@Z);
}
其中的函数内容一目了然。如果你的函数没有调用operator{不好理解的cdQ那么反~译出来的代码简直和源码没差别?nbsp;
开心一?/strong>Q我只会C++不懂.NET不懂C#Q怎么~写.NETE序Q?br>
很简单,你照L你的C++写你的程序,然后试没有错误后,编译选项改ؓ/clrQ好了,RebuildQ你的程序现在是.NET了?br>
恶搞Q?#8220;我想问一下,在能现有的CQ+代码直接q行装Q被CQ进行调用,而不是去调用DLLQ也是不生成DLLQ就在CQ下能直接调用VC的工E源文g不?”
我想Q提问的人是不是指,现有c++源码Q但不想费劲去{换成C#源码Q但又想能与C#一L译?br> 于是我就l了一个极其变态的ҎQ不q,个h是不使用q种变态的Ҏ啊。方法如下:
Q 先将C++源码Q改用CLR~译选项Q编译成.NET的AssemblyQDLL文gQ?
Q 然后用reflector{反~译软gQ反~译成C#代码Qƈ导出Qreflector有专门的导出插gQ?
Q 导出的C#代码Q添加上新写的C#代码一L译?
q种Ҏ生成的代码很是恐怖,强烈不要把C++源码p么丢了,否则后果自负?br>
场景?/strong>Q不惌DLLQ能不能直接把C++源代码与C#源代码一L译成一个单独的Assembly呢?
-------
部䆾例子来自MSDN.
]]>
]]>
By Mark Strawmyer
[源] http://www.developer.com/net/cplus/article.php/10919_1479761_1
What is .NET Remoting?
.NET Remoting versus Distributed COM
.NET Remoting versus Web Services
Channels
Create a Remotable Object
using System;
using System.Runtime.Remoting;
using System.Runtime.Remoting.Channels;
using System.Runtime.Remoting.Channels.Tcp;
namespace CodeGuru.Remoting
{
/// <remarks>
/// Sample object to demonstrate the use of .NET Remoting.
/// </remarks>
public class SampleObject : MarshalByRefObject
{
/// <summary>
/// Constructor
/// </summary>
public SampleObject()
{
}
/// <summary>
/// Return a hello message
/// </summary>
/// <returns>Hello world message</returns>
public string HelloWorld()
{
return "Hello World!";
}
}
}
Create a Server To Expose the Remotable Object
using System;
using System.Runtime.Remoting;
using System.Runtime.Remoting.Channels;
using System.Runtime.Remoting.Channels.Tcp;
namespace CodeGuru.Remoting
{
/// <remarks>
/// Sample server to demonstrate the use of .NET Remoting.
/// </remarks>
public class SampleServer
{
public static int Main(string [] args)
{
// Create an instance of a channel
TcpChannel channel = new TcpChannel(8080);
ChannelServices.RegisterChannel(channel);
// Register as an available service with the name HelloWorld
RemotingConfiguration.RegisterWellKnownServiceType(
typeof(SampleObject),
"HelloWorld",
WellKnownObjectMode.SingleCall );
System.Console.WriteLine("Press the enter key to exit...");
System.Console.ReadLine();
return 0;
}
}
}
Create a Client To Use the Remotable Object
using System;
using System.Runtime.Remoting;
using System.Runtime.Remoting.Channels;
using System.Runtime.Remoting.Channels.Tcp;
namespace CodeGuru.Remoting
{
/// <remarks>
/// Sample client to demonstrate the use of .NET Remoting.
/// </remarks>
public class SampleClient
{
public static int Main(string [] args)
{
// Create a channel for communicating w/ the remote object
// Notice no port is specified on the client
TcpChannel chan = new TcpChannel();
ChannelServices.RegisterChannel(chan);
// Create an instance of the remote object
SampleObject obj = (SampleObject) Activator.GetObject(
typeof(CodeGuru.Remoting.SampleObject),
"tcp://localhost:8080/HelloWorld" );
// Use the object
if( obj.Equals(null) )
{
System.Console.WriteLine("Error: unable to locate server");
}
else
{
Console.WriteLine(obj.HelloWorld());
}
return 0;
}
}
}
Test the Remoting Sample
Summary
Future Columns
About the Author
]]>
作者:TomMax (W望人生) 出处Qcsdn community
有许多h问的Q?Net中的委托以及事g处理。我拿简单的例子说明一下,是现实中的例子:
比如说一个公司(场景Q,你是老板Q手下有两个员工Q小张和王?br>你命令小王,如果张玩游戏,则小王扣d?00元钱?/p>
q就是现实中的委托?/p>
实际上,在写E序中,E序员就是老板Q小张和王是两个对象。小张玩游戏是一个方法,张q有一个游戏事Ӟ他玩游戏Ȁ发这个事件。而小王就是事件处理对象,他负责把张的钱扣除500?/p>
所以,委托有如下几个要素:
1 Ȁ发事件的对象--是张
2 处理对象事g的对?-是王
3 定义委托Q就是你让小王监视小张?/p>
如果q三个要素都满的话Q则你就写出了一个完整事件的处理?/p>
下面有个例子Q在vs.net2003 C#控制台应用程序编辑运行成功:
using System;
namespace CSharpConsole
{
public class 场景
{
[STAThread]
public static void Main(string[] args)
{
Console.WriteLine("场景开始了....");
// 生成王
王 w = new 王();
// 生成̎
张 z = new 张();
// 指定监视
z.PlayGame += new PlayGameHandler(w.扣钱);
// 开始玩游戏
z.玩游?);
console.writeline("场景l束...");
Console.ReadLine();
}
}
// 负责扣钱的h
public class 王
{
public 王()
{
Console.WriteLine("生成王...");
}
public void 扣钱(object sender,EventArgs e)
{
Console.WriteLine("王Q好子Q上班时间胆敢玩游戏...");
Console.WriteLine("王Q看看你子有多钱...");
张 f = (张)sender;
Console.WriteLine("张的钱Q?" + f.?ToString());
Console.WriteLine("开始扣?.....");
System.Threading.Thread.Sleep(500);
f.?= f.?- 500;
Console.WriteLine("扣完?...现在张q剩下:" + f.?ToString());
}
}
// 如果玩游戏,则引发事?br> public class 张
{
// 先定义一个事Ӟq个事g表示“张”在玩游戏?br> public event PlayGameHandler PlayGame;
// 保存张q变量
private int m_Money;
public 张()
{
Console.WriteLine("生成张....");
m_Money = 1000; // 构造函敎ͼ初始化小张的钱?br> }
public int ?// 此属性可以操作小张的钱?br> {
get
{
return m_Money;
}
set
{
m_Money = value;
}
}
public void 玩游?)
{
Console.WriteLine("张开始玩游戏?....");
Console.WriteLine("张:CS好玩Q哈哈哈Q?我玩.....");
System.Threading.Thread.Sleep(500);
System.EventArgs e = new EventArgs();
OnPlayGame(e);
}
protected virtual void OnPlayGame(EventArgs e)
{
if(PlayGame != null)
{
PlayGame(this,e);
}
}
}
// 定义委托处理E序
public delegate void PlayGameHandler(object sender,System.EventArgs e);
}