覆盖钩子函数中的现有指针
Overwriting existing pointer in hooked function
我有一个小问题,我似乎无法弄清楚。我挂钩了一个具有 char*
参数的函数,为了记录,挂钩正在工作。在我自己的函数中,我想将 char 指针参数更改为我自己的。
int Foo(char *buffer, int length)
{
//..
std::string cString(buffer);
// some changes are made to cString here
length = cString.length();
memcpy(buffer, cString.c_str(), length);
//..
}
现在,如果我保持新字符串的长度等于或小于旧字符串的长度,它就可以工作了。但如果我试图让它变大,它就不会起作用。
我该怎么做?我猜想在复制之前用新的长度重新分配缓冲区变量,但我无法让它以这种方式工作。
这根本不是 C 风格字符串 (char*
) 的工作方式。你问的不可能。
您应该将 C 字符串视为第一个字符的内存地址。负责从该地址开始的内存块大小的人是您的调用者。你不能在那里改变内存的大小。
举个例子,假设有人给了你他们家的地址,并要求你在里面放 1000 把椅子。这不可能,1000把椅子放不下,更不能放到邻居家。你也不能把房子变大,因为那意味着房子会和邻居的房子重叠。
您可以做的是分配新内存(在新位置建造新房子),用更大的数据填充它(用 1000 把椅子填充房子),然后return 返回新字符串的地址(返回房子的地址)。请记住告知您的来电者,他们现在有责任在完成房屋后将其摧毁。
一种方法是使用指向字符串的指针:
void f(const char* str, char** out) {
int len = strlen(str);
char* new_str = malloc(strlen + 5 + 1);
strcpy(new_str, str);
strcat(new_str + len, "world");
*out = new_str;
}
int main(int argc, char** argv) {
const char str[] = "hello ";
char* new_str;
f(str, &new_str);
printf("%s\n", new_str);
free(new_str);
return 0;
}
我有一个小问题,我似乎无法弄清楚。我挂钩了一个具有 char*
参数的函数,为了记录,挂钩正在工作。在我自己的函数中,我想将 char 指针参数更改为我自己的。
int Foo(char *buffer, int length)
{
//..
std::string cString(buffer);
// some changes are made to cString here
length = cString.length();
memcpy(buffer, cString.c_str(), length);
//..
}
现在,如果我保持新字符串的长度等于或小于旧字符串的长度,它就可以工作了。但如果我试图让它变大,它就不会起作用。
我该怎么做?我猜想在复制之前用新的长度重新分配缓冲区变量,但我无法让它以这种方式工作。
这根本不是 C 风格字符串 (char*
) 的工作方式。你问的不可能。
您应该将 C 字符串视为第一个字符的内存地址。负责从该地址开始的内存块大小的人是您的调用者。你不能在那里改变内存的大小。
举个例子,假设有人给了你他们家的地址,并要求你在里面放 1000 把椅子。这不可能,1000把椅子放不下,更不能放到邻居家。你也不能把房子变大,因为那意味着房子会和邻居的房子重叠。
您可以做的是分配新内存(在新位置建造新房子),用更大的数据填充它(用 1000 把椅子填充房子),然后return 返回新字符串的地址(返回房子的地址)。请记住告知您的来电者,他们现在有责任在完成房屋后将其摧毁。
一种方法是使用指向字符串的指针:
void f(const char* str, char** out) {
int len = strlen(str);
char* new_str = malloc(strlen + 5 + 1);
strcpy(new_str, str);
strcat(new_str + len, "world");
*out = new_str;
}
int main(int argc, char** argv) {
const char str[] = "hello ";
char* new_str;
f(str, &new_str);
printf("%s\n", new_str);
free(new_str);
return 0;
}