请解释之间有什么区别union和std::variant为什么 std::variant引入标准?我们应该在什么情况下使用std::variant旧学校union?
我有一个由dlsym()返回的void指针,我想调用void指针指向的函数.所以我通过强制转换进行类型转换:
void *gptr = dlsym(some symbol..) ;
typedef void (*fptr)();
fptr my_fptr = static_cast<fptr>(gptr) ;
Run Code Online (Sandbox Code Playgroud)
我也试过reinterpret_cast但没有运气,虽然C演员似乎工作..
我正在使用C库(来自C++),它提供以下接口:
void register_callback(void* f, void* data);
void invoke_callback();
Run Code Online (Sandbox Code Playgroud)
现在,我需要注册一个函数模板作为回调,这导致我的问题.请考虑以下代码:
template <typename T> void my_callback(void* data) { … }
int main() {
int ft = 42;
register_callback(reinterpret_cast<void*>(&my_callback<int>), &ft);
invoke_callback();
}
Run Code Online (Sandbox Code Playgroud)
这给了我以下链接器错误(在OS X上使用g ++(GCC)4.5.1,但适用于编译器版本/平台的大多数其他组合):
架构x86_64的未定义符号:
Run Code Online (Sandbox Code Playgroud)"void my_callback<int>(void*)", referenced from: _main in ccYLXc5w.o
我觉得这是可以理解的.
通过显式实例化模板可以轻松解决此问题:
template void my_callback<int>(void* data);
Run Code Online (Sandbox Code Playgroud)
不幸的是,这不适用于我的真实代码,因为回调是在函数模板中注册的,我不知道这个函数将被调用哪个模板参数集,因此我不能为所有的函数提供显式实例化.他们(我正在编写一个图书馆).所以我的真实代码看起来有点像这样:
template <typename T>
void do_register_callback(T& value) {
register_callback(reinterpret_cast<void*>(my_callback<T>), &value);
// Other things …
}
int main() {
int ft = 42;
do_register_callback(ft);
invoke_callback();
}
Run Code Online (Sandbox Code Playgroud)
通过调用函数隐式实例化函数模板.所以我们这样做,但要确保调用没有实际执行(该函数有副作用): …
void*以这样的方式定义,它可以指向任何东西.那么它可以用来指向一个函数(int send())吗?
int send();
void* p = send;
Run Code Online (Sandbox Code Playgroud)
可能吗?当我这样使用时,它没有向我显示错误原因?如果没有,有没有办法将所有指针存储在一个变量中?
如果我们必须保存任何数据类型的地址,那么我们需要该数据类型的指针.但是指针只是一个地址,而地址总是int类型,那么为什么任何数据类型的保持地址都需要该类型的指针?
我需要在运行时动态链接库并使用解析一系列函数dlsym.我的第一个想法是使用一个函数指针数组,通过利用char *表示符号名称的辅助数组,可以很容易地迭代.
但是,问题在于并非所有函数都使用相同的参数.有没有办法在数组中使用泛型函数指针,但是将它分配给限制性更强的函数指针原型?例如:
如果我需要解决这些功能:
int (*functionA)(int)
char (*functionB)(char,int)
Run Code Online (Sandbox Code Playgroud)
是否有可能做某些事情(伪似......)
void* functionList(...)[2] = {functionA, functionB};
Run Code Online (Sandbox Code Playgroud)
随着
char FuncNameA[] = "functionA";
char FuncNameB[] = "functionB";
char *functionNames[2] = {FuncNameA, FuncNameB};
Run Code Online (Sandbox Code Playgroud)
用于循环调用dlsym符号解析的目的
int i = 0;
for(; i<2; i++)
functionList[i] = dlsym(DL_OPEN_HANDLE, functionNames[i]);
Run Code Online (Sandbox Code Playgroud)
其中DL_OPEN_HANDLE将由之前的调用定义dlopen.
可能重复:
为什么函数指针和数据指针在C/C++中不兼容?
在dlsym的手册页中,提供了以下代码段.
double (*cosine)(double);
handle = dlopen("libm.so", RTLD_LAZY);
/* Writing: cosine = (double (*)(double)) dlsym(handle, "cos");
would seem more natural, but the C99 standard leaves
casting from "void *" to a function pointer undefined.
The assignment used below is the POSIX.1-2003 (Technical
Corrigendum 1) workaround; see the Rationale for the
POSIX specification of dlsym(). */
*(void **) (&cosine) = dlsym(handle, "cos");
Run Code Online (Sandbox Code Playgroud)
我查看了相关的spec页面,但仍然无法理解不允许从void指针转换为函数指针的原因.虚假指针应该足够大,以容纳所有类型的指针.如果是这样,为什么不定义这个铸件呢?
我的问题主要是专注于教授,并且是以"奇怪"的方式使用C++.在C++中,指向变量的指针和指向函数的指针之间没有太大区别.我们可以做一些像这样无用的事情:
char* buff = new char[32];
void (*func)() = (void (*)())buff;
Run Code Online (Sandbox Code Playgroud)
但我们几乎创造了一个从未存在的功能,对吗?如果我们进一步用文件中的x86命令stord填充buff怎么办?操作系统永远不会知道创建了一个函数.
#include <iostream>
using namespace std;
// no stack push'ing or pop'ing, nothing to return
void func(void){cout << "Hello?";}
int main()
{
char* x86_code = new char[6];
x86_code[0] = 0x9A; // call (far)
*((__int32*)(x86_code + 1)) = (__int32)func; // load 32-bit address
x86_code[5] = 0xC3; // ret
void (*x86_func)(void) = (void (*)(void))x86_code;
x86_func();
return 0;
}
Run Code Online (Sandbox Code Playgroud)
调用x86_func()会产生运行时错误(违反读取位置0xFFFFFFFF).如果不是这样,操作系统如何在RAM中加载它的二进制文件或模块?非常感谢.
void funcPtr(int a);
int main(){
int k=1;
void (*funcPtr2)(int);
funcPtr2 = (void*)(funcPtr);
// funcPtr2 = (void(*)(int))(funcPtr);
(*funcPtr2)(k);
return 0;
}
void funcPtr(int a){
printf("%d", a);
}
Run Code Online (Sandbox Code Playgroud)
(void*)和(void(*)(argument type)函数指针类型转换有什么区别?
因此,它不会发生警告.
这是错的吗?关于(void*)型铸造
我想定义一个函数类型,它返回一个指向同一类型函数的指针.我试过这个:
typedef state* (*state)(lex*);
Run Code Online (Sandbox Code Playgroud)
但我得到的syntax error就像你猜的那样.