重新定义一个void*的handle ptr来handle ptr to struct* (C/C++ mixcode)进行访问
Redefining a handle ptr of void* to handle ptr to struct* (C/C++ mixcode) for access
我有 C/C++ 混合代码,想传递一个包含对 class 的引用的结构。因此,我无法在 C++ 组件的头文件中声明此结构(因为 class 在 C++ 组件的源文件中定义),而只能在源文件中声明。然而,C 中的主脚本必须以某种方式引用该结构,因此我将其类型定义为 void*。但是正因为如此,我无法将句柄类型取消引用回结构。无法在源文件中重新定义句柄指针。我该如何解决这个问题?
header_with_obj.hpp
class A {
int a;
};
header.hpp
typedef void* config_handle_t;
source.cpp
#include "header.hpp"
#include "header_with_obj.hpp"
typedef struct {
A* ptr;
int some_other;
} config_t;
// typedef config_t* config_handle_t <-- error: conflicting declaration 'typedef struct config_t* config_handle_t '
int foo(void* arg)
{
config_handle_t handle = (config_handle_t) arg;
handle->A.a = 4; // <-- error: 'config_handle_t' {aka 'void*'} is not a pointer-to-object type
}
main.c
#include "header.hpp"
int main()
{
// we get that void* from somewhere and pass it in
foo(arg);
}
通常的做法是使用未定义的结构。最基本的形式:
void foo(struct the_config_struct *arg);
// OK even though 'struct the_config_struct' wasn't defined!
// surprisingly this is also allowed in C++
你也可以做一个typedef:
typedef struct the_config_struct *config_handle_t;
void foo(config_handle_t arg);
如果需要,您甚至可以像调用结构一样调用 typedef。为了避免混淆人们,我不会这样做,除非它是 typedef for the struct(不是指针)。
typedef struct the_config_struct the_config_struct;
void foo(the_config_struct *arg);
在您想要访问其成员之前,您实际上并没有定义该结构:
// if we uncomment this definition then it's OK
// struct my_struct {
// char *message;
// };
void foo(struct my_struct *arg) {
puts(arg->message); // error: struct my_struct is undefined
}
最后(因为这之前让你感到困惑)你应该知道 typedef 名称和结构名称在 C 中是完全分开的。
struct foo {}; // defines "struct foo" but "foo" is completely unrelated
typedef int bar; // defines "bar" but "struct bar" is completely unrelated
foo *get_foo(); // error: "foo" is unknown
struct foo *get_foo(); // OK
typedef struct bar foo;
foo *get_bar(); // OK: returns pointer to struct bar (not struct foo!)
struct foo *get_foo(); // this one returns pointer to struct foo
struct baz {};
typedef struct baz baz;
// now "baz" is an alternative name for "struct baz" - they are interchangeable
typedef struct baz {} baz; // short version
并且结构不必有名称:
// foo is a variable, and it's a struct variable, but the struct has no name.
// so we have no way to use the struct for anything else.
struct {
int i;
} foo;
// The struct is still there even though it doesn't have a name!
// In C++ you can write decltype(bar) to say "the same type as variable bar".
// Even though we don't know the person's name we can still yell out "Hey you in the red shirt!"
decltype(foo) foo2; // a variable foo2. The type is decltype(foo) i.e. the struct from before
// GCC lets you do it in C using "typeof".
// This is not standard. It's a special feature in GCC.
typeof(foo) foo2;
// This struct also has no name either. But the typedef means we have
// an "unofficial" way to name it, just like decltype(foo) before.
// This is valid in C as well as C++.
typedef struct {
char message[50];
} bar;
我有 C/C++ 混合代码,想传递一个包含对 class 的引用的结构。因此,我无法在 C++ 组件的头文件中声明此结构(因为 class 在 C++ 组件的源文件中定义),而只能在源文件中声明。然而,C 中的主脚本必须以某种方式引用该结构,因此我将其类型定义为 void*。但是正因为如此,我无法将句柄类型取消引用回结构。无法在源文件中重新定义句柄指针。我该如何解决这个问题?
header_with_obj.hpp
class A {
int a;
};
header.hpp
typedef void* config_handle_t;
source.cpp
#include "header.hpp"
#include "header_with_obj.hpp"
typedef struct {
A* ptr;
int some_other;
} config_t;
// typedef config_t* config_handle_t <-- error: conflicting declaration 'typedef struct config_t* config_handle_t '
int foo(void* arg)
{
config_handle_t handle = (config_handle_t) arg;
handle->A.a = 4; // <-- error: 'config_handle_t' {aka 'void*'} is not a pointer-to-object type
}
main.c
#include "header.hpp"
int main()
{
// we get that void* from somewhere and pass it in
foo(arg);
}
通常的做法是使用未定义的结构。最基本的形式:
void foo(struct the_config_struct *arg);
// OK even though 'struct the_config_struct' wasn't defined!
// surprisingly this is also allowed in C++
你也可以做一个typedef:
typedef struct the_config_struct *config_handle_t;
void foo(config_handle_t arg);
如果需要,您甚至可以像调用结构一样调用 typedef。为了避免混淆人们,我不会这样做,除非它是 typedef for the struct(不是指针)。
typedef struct the_config_struct the_config_struct;
void foo(the_config_struct *arg);
在您想要访问其成员之前,您实际上并没有定义该结构:
// if we uncomment this definition then it's OK
// struct my_struct {
// char *message;
// };
void foo(struct my_struct *arg) {
puts(arg->message); // error: struct my_struct is undefined
}
最后(因为这之前让你感到困惑)你应该知道 typedef 名称和结构名称在 C 中是完全分开的。
struct foo {}; // defines "struct foo" but "foo" is completely unrelated
typedef int bar; // defines "bar" but "struct bar" is completely unrelated
foo *get_foo(); // error: "foo" is unknown
struct foo *get_foo(); // OK
typedef struct bar foo;
foo *get_bar(); // OK: returns pointer to struct bar (not struct foo!)
struct foo *get_foo(); // this one returns pointer to struct foo
struct baz {};
typedef struct baz baz;
// now "baz" is an alternative name for "struct baz" - they are interchangeable
typedef struct baz {} baz; // short version
并且结构不必有名称:
// foo is a variable, and it's a struct variable, but the struct has no name.
// so we have no way to use the struct for anything else.
struct {
int i;
} foo;
// The struct is still there even though it doesn't have a name!
// In C++ you can write decltype(bar) to say "the same type as variable bar".
// Even though we don't know the person's name we can still yell out "Hey you in the red shirt!"
decltype(foo) foo2; // a variable foo2. The type is decltype(foo) i.e. the struct from before
// GCC lets you do it in C using "typeof".
// This is not standard. It's a special feature in GCC.
typeof(foo) foo2;
// This struct also has no name either. But the typedef means we have
// an "unofficial" way to name it, just like decltype(foo) before.
// This is valid in C as well as C++.
typedef struct {
char message[50];
} bar;