简体   繁体   English

在C ++中将成员函数转换为静态函数

[英]Converting a member function to a static function in C++

I am writing a memory testing framework, in which I replace dynamic memory allocation functions with my own (eg. malloc, realloc, free, etc.). 我正在编写一个内存测试框架,在其中我用自己的内存替换动态内存分配函数(例如,malloc,realloc,free等)。 However, the system expects static functions (I can not change this). 但是,系统需要静态函数(我不能改变它)。

I have a MemoryTester class, which logs the memory calls, and I want to bind its member function implementations of the memory allocation functions. 我有一个MemoryTester类,它记录内存调用,我想绑定其内存分配函数的成员函数实现。 Is this possible with C++? 这可能用C ++吗?

EDIT: 编辑:

Here is some code highlighting what I'm trying to do: 这是一些突出我正在尝试做的代码:

typedef void*(allocateFuncPtr) (uint8_t);
typedef void (freeFuncPtr) (void*);

void setAllocateFunction(allocateFuncPtr) {...}
void setFreeFunction(freeFuncPtr) {...}


class MemoryTester
{
    void *malloc(uint8_t size);
    void free(void *ptr);
}

int main()
{
    MemoryTester *tester = new MemoryTester();

    //want to set allocate and free functions to those in tester
    setAllocateFunction( tester->getAllocateFunction() );
    setFreeFunction( tester->getFreeFunction() );

    return 0;
}

After the edit, the intent seems clearer to me. 编辑后,我的意图似乎更清楚了。 The simplest thing that you can do is using static member functions in the MemoryTester instead of non-static member functions. 您可以做的最简单的事情是在MemoryTester使用静态成员函数而不是非静态成员函数。 If they need to hold state, that state will have to be moved to be static members of the class. 如果他们需要保持状态,则必须将该状态移动为该类的static成员。

If your compiler supports 0x lambdas, you can use a closure: 如果您的编译器支持0x lambdas,则可以使用闭包:

int main() {
  MemoryTester tester;  // If no need for dynamic allocation, don't use it.

  setAllocateFunction([&tester](uint8_t size) { return tester.malloc(size); });
  setFreeFunction([&tester](void *p) { tester.free(p); });

  return 0;
}

No changes required to your MemoryTester class nor whichever library setAllocateFunction & setFreeFunction belong to. 您的MemoryTester类不需要更改,也不需要setAllocateFunction和setFreeFunction所属的库。


Without lambdas, instead of a singleton class , use a single global object: 如果没有lambda,而不是单例类 ,请使用单个全局对象:

struct MemoryTester {
  void* malloc(uint8_t size);  // Neither are static.
  void free(void *p);
};

MemoryTester tester_a;
void* tester_a_malloc(uint8_t size) { return tester_a.malloc(size); }
void tester_a_free(void *p) { return tester_a.free(p); }

int main() {
  setAllocateFunction(&tester_a_malloc);
  setFreeFunction(&tester_a_free);
}

The advantage here is the entire MemoryTester class isn't hamstrung because of one particular need for it. 这里的优点是整个MemoryTester类没有因为它的特殊需要而受到限制 You can create more functions (eg tester_b_malloc/free) as needed to accommodate other uses within the same program. 您可以根据需要创建更多功能(例如tester_b_malloc / free)以适应同一程序中的其他用途。

If you are using GCC, then you can have the linker wrap the function for you with the --wrap option ( or -Wl,--wrap,malloc ). 如果您正在使用GCC,那么您可以让链接器使用--wrap选项(或-Wl, - wrap,malloc)为您包装该函数。

Then you can intercept calls to malloc because all calls to that function will be redirected to __wrap_malloc. 然后你可以拦截对malloc的调用,因为对该函数的所有调用都将被重定向到__wrap_malloc。 You can call the real (original c-lib) malloc function using the name __real_malloc or you can substitute a replacement of your own (and if __real_malloc isn't called, then the linker may be able to dead-strip out the original c-lib malloc all-together). 你可以使用名称__real_malloc来调用真实的(原始c-lib)malloc函数,或者你可以替换你自己的替换(如果没有调用__real_malloc,那么链接器可能能够删除原来的c- lib malloc all-together)。

void *__wrap_malloc (size_t c)
{
  printf ("malloc called with %zu\n", c);
  return __real_malloc (c);
}

FWIW, you can replace the global new and delete operations and then you can have a program using only your own memory system (even when you use code from 3rd party compiled libraries as long as they haven't overloaded global new and delete). FWIW,您可以替换全局的new和delete操作,然后您可以只使用自己的内存系统(即使您使用第三方编译库中的代码,只要它们没有重载全局new和delete)。

Here's some great info: Tutorial of Replacing "new" and "delete" 这里有一些很棒的信息: 替换“新”和“删除”的教程

If I understand correctly what you ask, there is no "binding" to do. 如果我理解你的要求,就没有“约束力”。 Once the memory have been allocated, you can tell the compiler it's type by user a cast, in your case a reinterpret_cast. 一旦分配了内存,就可以告诉编译器用户输入一个类型,在你的情况下是一个reinterpret_cast。 For example, in you allocation function: 例如,在你的分配函数中:

unsigned char* raw_memory = allocation( std::size_t );
MyFinalType* object = reinterpret_cast<MyFinalType*>(raw_memory); // tells the compiler to take this memory as a MyFinalType.

Then you return your final type. 然后你返回你的最终类型。

To know wich type to use, you'll certainly want to use templates. 要知道要使用的类型,您肯定想要使用模板。

Don't forget that C++ is a statically typed language: you can't bind functions to an object type. 不要忘记C ++是一种静态类型语言:您不能将函数绑定到对象类型。 Ok you can, but the, you have to use std::function or function pointers, that are not what you want here. 好的,你可以,但是,你必须使用std :: function或函数指针,这不是你想要的。

Not unless you make a global object. 除非您创建一个全局对象。 If the framework takes regular function pointers, then you're stuck with what it provides, and if it doesn't provide for the traditional void* userdata style, then you're stuffed, or it's global object time. 如果框架采用常规函数指针,那么你就会坚持使用它提供的内容,如果它没有提供传统的void * userdata样式,那么你就会被填充,或者它是全局对象时间。

拥有一个单独的MemoryTester对象,并具有调用该对象的成员函数的桥接静态函数。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM