用我自己的实现替换getpid

时间:2009-04-28 03:24:29

标签: c++

我有一个应用程序,我需要编写一个新的getpid函数来替换原来的操作系统。实施类似于:

pid_t getpid(void)
{
    if (gi_PID != -1)
    {
        return gi_PID;
    }
    else
    {
        // OS level getpid() function
    }
}

如何通过此函数调用OS的原始getpid()实现?

编辑:我试过了:

pid_t getpid(void)
{
    if (gi_PID != -1)
    {
        return gi_PID;
    }
    else
    {
        return _getpid();
    }
}
正如乔纳森所说的那样。在使用g ++进行编译时,这给了我以下错误:

  

在函数pid_t getpid()': SerendibPlugin.cpp:882: error: _ getpid'未声明(首先使用此   函数)SerendibPlugin.cpp:882:   错误:(每个未声明的标识符是   每个功能仅报告一次   它出现在。)

编辑2:我已经设法通过使用函数指针并使用dlsym(RTLD_NEXT,“getpid”)将其设置为ID为“getpid”的下一个第二个符号来实现此功能。

这是我的示例代码:

vi xx.c
"xx.c" 23 lines, 425 characters 
#include <sys/types.h>
#include <unistd.h>
#include <stdio.h>
#include <iostream>
#include <dlfcn.h>

using namespace std;
pid_t(*___getpid)();

pid_t getpid(void)
{
    cout << "My getpid" << endl;
    cout << "PID :" << (*___getpid)() << endl;
    return (*___getpid)();
}

int main(void)
{
    ___getpid = (pid_t(*)())dlsym(RTLD_NEXT, "getpid");
    pid_t p1 = getpid();
    printf("%d \n", (int)p1);
    return(0);
}

g ++ xx.c -o xout

My getpid
PID :7802
7802 

3 个答案:

答案 0 :(得分:4)

在许多系统上,您会发现getpid()_getpid()的'弱符号',可以代替getpid()调用。


答案的第一个版本提到__getpid();由于它是错误的,因此提及被迅速删除。

此代码适用于Solaris 10(SPARC) - 使用C ++编译器:

#include <sys/types.h>
#include <unistd.h>
#include <stdio.h>

extern "C" pid_t _getpid();

pid_t getpid(void)
{
    return(-1);
}

int main(void)
{
    pid_t p1 = getpid();
    pid_t p2 = _getpid();
    printf("%d vs %d\n", (int)p1, (int)p2);
    return(0);
}

此代码适用于Solaris 10(SPARC) - 使用C编译器:

Black JL: cat xx.c
#include <sys/types.h>
#include <unistd.h>
#include <stdio.h>

pid_t getpid(void)
{
    return(-1);
}

int main(void)
{
    pid_t p1 = getpid();
    pid_t p2 = _getpid();
    printf("%d vs %d\n", (int)p1, (int)p2);
    return(0);
}
Black JL: make xx && ./xx
cc     xx.c   -o xx
"xx.c", line 13: warning: implicit function declaration: _getpid
-1 vs 29808
Black JL:

答案 1 :(得分:1)

您可以使用宏:

在.h中,包含在要替换getpid函数

的每个文件中
#define getpid() mygetpid()

然后,将您自己的实现放在.cpp

pid_t mygetpid() {
    // do what you want
    return (getpid)();
}

答案 2 :(得分:0)

您使用的术语有点不正确。覆盖getpid()是不可能的,因为它不是虚函数。你所能做的就是尝试用各种邪恶手段用不同的功能取代getpid。

但我必须问,你为什么要这样做?替换getpid意味着任何依赖于getpid返回的组件现在都会接收到你的修改结果。此更改具有更改某些其他组件的高风险。

您提供的是新功能,因此应该是不同的功能。

如果您真的想采用这种方法,最好的方法是动态加载函数。原始DLL仍将包含getpid函数,您可以通过Windows上的LoadLibrary / GetProcAddress或Linux上的dlopen / dlsym的组合来访问它。如果您使用的是其他操作系统,请指定。

编辑响应getpid需要测试的评论

如果测试是关注点,那么为什么不为您的应用程序提供自定义getpid方法。例如,applicationGetPid()。对于正常执行,可以将其转发到系统getpid函数。但在单元测试期间,它可用于产生更可预测的值。

pid_t applicationGetPid() { 
#if UNIT_TEST
return SomeCodeForUnitTests;
#else
return getpid();
#endif
}