在进程间移动数据

时间:2010-09-05 01:25:49

标签: delphi dll

我问这个的原因是寡妇不支持在进程之间进行通信的好方法。所以我想为Windows进程之间的通信点创建一个DLL。线程由进程拥有,不能提供给另一个进程。 每个线程都有自己的堆栈。 如果加载了DLL(loadlibray)并且调用了一个DLL函数,它会向windows请求内存。我写的是认为线程仍然由同一进程拥有并将内存分配到同一进程中。

所以我想我可以转向程序集将一个小内存块重新分配给另一个进程。创建一个关键部分,将数据复制到另一个(已创建的)内存块,并使用out up设置窗口返回原始块到其原始进程。有没有人以前这样做过。或者是更好的方式。

祝你好运, Lex Dean。


我看到其他方法相当快,但我想要一个非常快速的方法。管道和互联网显然可以工作,但不是最好的选择,但很容易实现(感谢提供这样的建议家伙)。我想有时会以相当规律的间隔发送相当多的500字节块。我喜欢WM_COPYDATA因为它看起来很快,我在互联网上一直在寻找的最大问题是: - GetCurrentProcess和DuplicateHandle来获得真正的处理。寻找其他过程。并使用消息设置内存,然后使用WM_COPYDATA。我只需要两条消息a)指针和大小b)数据已被复制。        我的应用程序过程很容易'GetCurrentProcess',除了它是一个伪句柄,总是$ FFFFFFE。我需要真正的进程句柄,互联网上没有任何正文提供了DuplicateHandle的示例。这就是让我难过的原因。你能告诉我一个DuplicateHandle的例子吗,那是什么让我难过?

我不喜欢转到表格来获取句柄,因为一个应用程序并不总是具有当前形式。 我不喜欢转向一个表格来获取句柄,因为一个应用程序并不总是具有当前形式。             在Delphi中,我已经看到使用TSpeedButton发送消息,以便在应用程序之间建立一个简单的快速通信方法,我估计这些方法最常使用大约80条指令。所以我仍然想着思考dll。 Mads Elvheim发送的示例与我已经知道的相同。               我仍然愿意理解使用我自己的* .Dll的任何其他选项 因为我的应用程序对我很重要,所以只需在* .DLL上注册/取消注册它自己的进程,而不是一直搜索以查看进程是否是最新的。 这是我在进程之间使用* .DLL管理内存的方式,但我没有被告知。 对我来说DLL并不难实现,因为我已经有了自己的操作。

真正的底线是访问窗口以创建一个好的选择。因为我对想法很开放。甚至是进程之间的组装指令或Windows调用。但是我不知道通过做违法的事情让法庭崩溃。 所以请举例说明你做了什么,这是我的需要。这很快,我很感兴趣,因为我最有可能会使用它。

6 个答案:

答案 0 :(得分:7)

我有一个基于命名管道的非常快速的IPC(进程间通信)解决方案。它非常快速且易于使用(它隐藏了您的实际实现。您只需使用数据包)。还经过测试和验证。你可以在这里找到代码和演示。

http://www.cromis.net/blog/downloads/cromis-ipc/

它也适用于同一局域网中的计算机。

答案 1 :(得分:4)

如果您的进程有消息循环(带有窗口),您可以使用WM_COPYDATA消息发送/接收序列化数据http://msdn.microsoft.com/en-us/library/ms649011(VS.85).aspx

请记住,只允许读取为COPYDATASTRUCT :: lpData成员分配的内存。同样,不能传递具有指针的结构。数据必须是序列化的。并且接收方只能读取这个结构,它不能写入它。例如:

/* Both are conceptual windows procedures. */

/* For sending : */
{
    ...
    TCHAR msg[] = _T("This is a test\r\n");
    HWND target;
    COPYDATASTRUCT cd = {0};
    cd.lpData = _tcsdup(msg); // We allocate and copy a string, which is fine.
    cd.cbData = _tcsclen(msg) + 1; //The size of our data. Windows needs to know this.
    target = FindWindow(..); //or EnumProcesses
    SendMessage(target, WM_COPYDATA, (LPARAM)hwnd, (WPARAM)&cd);
}

/* For receiving */
{
    ...
    case WM_COPYDATA:
    {
        TCHAR* msg;
        COPYDATASTRUCT* cb = (COPYDATASTRUCT*)wParam;
        sender = FindWindow(..); //or EnumProcesses

        //check if this message is sent from the window/process we want
        if(sender == (HWND)lParam){
            msg = _tcsdup(cb->ldData);
            ...
        }
        break;
    }
}

否则,请使用内存映射文件或网络套接字。

答案 2 :(得分:1)

我目前在Delphi中使用Mailslots来实现它并且它非常有效。

答案 3 :(得分:0)

“Win32 DLL被映射到调用进程的地址空间。默认情况下,每个使用DLL的进程都有自己的所有DLL全局和静态变量的实例。如果你的DLL需要与其他实例共享数据在其他应用程序加载后,您可以使用以下任一方法:

•使用data_seg pragma创建命名数据部分。 •使用内存映射文件。请参阅有关内存映射文件的Win32文档。“

http://msdn.microsoft.com/en-us/library/h90dkhs0(VS.80).aspx

你不能在进程之间共享指针,它们只对分配它的进程有意义。你可能会遇到问题。

答案 4 :(得分:0)

Win32与此方面的任何其他现代操作系统没有什么不同。 Windows中有大量的IPC服务供您使用。

尝试描述你要解决的任务 - 而不是“......然后我认为我需要在这里复制那块内存......”。这不是你的任务。您的客户没有说您:“我想将线程从一个进程转移到另一个进程”。

答案 5 :(得分:0)

我可以问任何人使用过: - DllMain回调函数 我理解线程不能重新定位到另一个进程,只留下一个选项来通信进程。多数民众赞成使用消息,没关系。

 What I understand is when accessing a file, the internet scoket, and all thouse things. The DOS 640k memory block is used with the processors DS register. 

并且dll在每个使用dll名称调用loadlibray的进程中都有一个内存空间。所以我的想法是: - 当内存空间被替换为dll时,所有进程都可以扩展和访问该空间。