相关疑难解决方法(0)

哪里使用std :: variant而不是union?

请解释之间有什么区别unionstd::variant为什么 std::variant引入标准?我们应该在什么情况下使用std::variant旧学校union

c++ c++17

44
推荐指数
1
解决办法
8125
查看次数

用C++编写的函数指针

我有一个由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++ casting function-pointers

38
推荐指数
2
解决办法
6万
查看次数

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的未定义符号:

"void my_callback<int>(void*)", referenced from:  
  _main in ccYLXc5w.o
Run Code Online (Sandbox Code Playgroud)

我觉得这是可以理解的.

首个"解决方案"

通过显式实例化模板可以轻松解决此问题:

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)

第二"解决方案"

通过调用函数隐式实例化函数模板.所以我们这样做,但要确保调用没有实际执行(该函数有副作用): …

c++ macos templates undefined-reference gcc4

14
推荐指数
3
解决办法
2705
查看次数

can void*用于存储函数指针?

void*以这样的方式定义,它可以指向任何东西.那么它可以用来指向一个函数(int send())吗?

int send();
void* p = send;
Run Code Online (Sandbox Code Playgroud)

可能吗?当我这样使用时,它没有向我显示错误原因?如果没有,有没有办法将所有指针存储在一个变量中?

c c++ function-pointers void-pointers

14
推荐指数
2
解决办法
3079
查看次数

为什么不同类型的指针用于c中的不同数据类型?

如果我们必须保存任何数据类型的地址,那么我们需要该数据类型的指针.但是指针只是一个地址,而地址总是int类型,那么为什么任何数据类型的保持地址都需要该类型的指针?

c

12
推荐指数
2
解决办法
4300
查看次数

在C中是否存在可以分配/转换为更具限制性的原型的通用函数指针?

我需要在运行时动态链接库并使用解析一系列函数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 function-pointers dynamic-linking

12
推荐指数
3
解决办法
4544
查看次数

C:为什么从void指针转换为函数指针未定义?

可能重复:
为什么函数指针和数据指针在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 function-pointers void-pointers

11
推荐指数
0
解决办法
1655
查看次数

如何从数据缓冲区执行x86命令?

我的问题主要是专注于教授,并且是以"奇怪"的方式使用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中加载它的二进制文件或模块?非常感谢.

c++ x86 module

7
推荐指数
1
解决办法
2078
查看次数

(void*)和(void(*)(参数类型))cast之间有什么区别?

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*)型铸造

c c++ pointers

7
推荐指数
1
解决办法
1127
查看次数

是否可以在C中进行递归类型定义

我想定义一个函数类型,它返回一个指向同一类型函数的指针.我试过这个:

typedef state* (*state)(lex*);
Run Code Online (Sandbox Code Playgroud)

但我得到的syntax error就像你猜的那样.

c syntax types

6
推荐指数
0
解决办法
423
查看次数