创建跨进程函数指针

Pau*_*ulH 4 c++ windows function-pointers

我有一个Windows Mobile 6的Visual Studio 2008 C++项目,有两个进程.我想要访问process1中包含的同一个函数.

那个功能是Buzz:

struct TEST_STRUCT
{
    int bar;
    WCHAR foo[ 20 ];
};

typedef int( *pfn_Buzz )( TEST_STRUCT* );

int Buzz( TEST_STRUCT* info );
Run Code Online (Sandbox Code Playgroud)

Process1包含定义,Buzz并在内存映射文件中为其创建函数指针:

int Buzz( TEST_STRUCT* info )
{
    info->bar = 1;
    wsprintf( info->foo, L"Hello!" );
    return 100;
}

int _tmain( int argc, _TCHAR* argv[] )
{
    // create a memory-mapped file shared memory space that can be read by any process
    HANDLE mapping = ::CreateFileMapping( INVALID_HANDLE_VALUE, NULL, PAGE_READWRITE, 0, sizeof( pfn_Buzz ) , NULL );
    LPVOID buzz_addr = ::MapViewOfFile( mapping, FILE_MAP_ALL_ACCESS, 0, 0, sizeof( pfn_Buzz ) );

    // find our process' memory offset
    DWORD offset = ::GetCurrentProcessIndex() + 0x02000000;

    // copy the complete function address to the shared memory space
    buzz_addr = ( LPVOID )( ( DWORD )&Buzz + offset );

    // convert the function address to a string to send to process2.exe
    WCHAR address[ 9 ] = { 0 };
    wsprintf( address, L"%x", ( ( DWORD )buzz_addr ) );

    // start process2.exe and wait for it to finish
    PROCESS_INFORMATION pi = { 0 };
    ::CreateProcess( L"\\test_user.exe", address, NULL, NULL, FALSE, 0, NULL, NULL, NULL, &pi );
    ::WaitForSingleObject( pi.hProcess, INFINITE );

    ::UnmapViewOfFile( buzz_addr );
    ::CloseHandle( mapping );

    return 0;
}
Run Code Online (Sandbox Code Playgroud)

Process2 Buzz从Process1 接收地址,将其强制转换为pfn_Buzz函数指针,然后执行它.

// process2.exe
int _tmain( int argc, _TCHAR* argv[] )
{
    // get the address of the Buzz() function pointer
    WCHAR* wszAddr = argv[ 1 ];
    WCHAR* wszAddrEnd = &argv[ 1 ][ 8 ];
    DWORD address = wcstol( wszAddr, &wszAddrEnd, 16 );
    pfn_Buzz PFNBuzz = ( pfn_Buzz )address;

    // execute buzz
    TEST_STRUCT test = { 0 };
    PFNBuzz( &test );

    return 0;
}
Run Code Online (Sandbox Code Playgroud)

不幸的是,当我尝试执行该PFNBuzz函数时,我在process2中遇到了非法指令异常.

任何人都可以建议我可以改变以获得我追求的功能吗?

谢谢,PaulH

Goz*_*Goz 6

您的问题来自于进程A(启动进程B)具有2个完全不同的虚拟地址空间.您可以将一个函数指针传递给进程A,但是当它们的地址空间不同时,您传递的任何指针都会减少到另一个进程.这是流程的巨额奖金之一.

如果您希望在进程之间进行通信,则需要使用某种形式的进程间通信(IPC).

有几种方法可以在Windows下进行IPC.在我看来,最通用的方法是使用套接字.套接字为您提供的优势是,您可以分离运行进程A和进程B的计算机,并仍然可以获得所需的功能.同样,没有什么能阻止在同一台机器上运行的两个进程.它提供的灵活性非常有用.

因此,假设您选择基于套接字的IPC方法,那么您实际执行的是远程过程调用(RPC).

正如您可以想象的那样,有许多不同的RPC方法.你可以使用DCOMCorba. Raknet是支持RPC的第三方库.还有许多其他解决方案.我强烈建议对此事进行大量研究.我提供给你的链接和关键字应该给你一个很好的起点:)