将 void 指针转换为 2D String 数组指针

Casting a void pointer to a 2D String array pointer

提问人:ManWithNoName 提问时间:6/2/2023 最后编辑:Rabbid76ManWithNoName 更新时间:11/19/2023 访问量:301

问:

我正在使用一个库,它需要一个带有指针作为参数的函数。我有一个 2D 字符串数组,我想通过该参数传递该数组并将其提取到函数中。我成功地将数组作为指针传递,但我不知道如何将该指针转换回我的数组。void*

这是我当前的代码:

String str_array[100][10];

int callback(void* data) {

  String* str_array_ptr[100][10] = (String* [100][10])data;

  (*str_array_ptr)[0][0] = "text";

  return 0;

}

void test() {
  callback(&str_array);
}

但是,在编译时,我收到以下错误消息:

错误:ISO C++ 禁止转换为数组类型“String* [100][10]' [-fpermissive]

PS:我正在尝试使用SQLite库的函数并将“SELECT SQL查询”的结果存储到2D字符串数组中。sqlite3_exec()

SQLite C 接口 - 一步式查询执行接口

C++ 数组 指针 转换 void-pointers

评论

0赞 ManWithNoName 6/2/2023
我正在使用 Arduino IDE,我们可以混合 C 和 CPP 文件。
1赞 n. m. could be an AI 6/2/2023
没有 C/CPP 这样的东西。 不是标准的 C++ 类型。在 C++ 中,我们避免了 C 样式数组、原始指针、空指针和强制转换。 是一个 100x10 的指针数组。如果需要指向数组的指针,最好的选择是使用 .StringString* [100][10]Stringtypedef
0赞 Adrian Mole 6/2/2023
@Jason 在这两个所谓的“重复项”中,没有任何关于强制转换为 2D 数组指针的内容。我将重新讨论这个问题......
2赞 user12002570 6/2/2023
@AdrianMole 仅仅在问题标题中包含“铸造”并不能构成关于铸造的问题。
2赞 user12002570 6/2/2023
@AdrianMole 这里没有什么可假设的。仅仅因为标题包含“铸造”一词并不意味着问题必须与铸造有关,或者问题与铸造有关。副本解决了 OP 的问题。

答:

5赞 john 6/2/2023 #1

不能将指针强制转换为数组。相反,您可以通过另一个指针访问您的数组。该指针的类型为 。喜欢这个String (*)[10]

String str_array[100][10];

int callback(void* data) { 

    String (*str_array_ptr)[10] = (String (*)[10])data;

    str_array_ptr[0][0] = "text"; // Note no '*'

    return 0;

}

void test() {
    callback(str_array); // Note no '&'
}

创建指针的方式(不需要使用)和访问指针的方式(不需要使用)在代码中也是错误的。有关详细信息,请参阅上面的代码。&*

这里的根本问题(也许是你误解的问题)是 和 之间的区别。在第一种情况下是指向 10 个指针的数组,在第二种情况下是指向 10 个数组的指针。这是您想要的第二个选项。String *x[10];String (*x)[10];xStringxString

评论

0赞 ManWithNoName 6/2/2023
你是对的,我混淆了“指针数组”和“指向数组的指针”语法。也许我需要多睡一会儿!谢谢
0赞 Adrian Mole 6/2/2023
只是一个小小的吹毛求疵:这个问题被标记为 C++,那么为什么是 C 风格的演员呢?
0赞 ManWithNoName 6/3/2023
@AdrianMole这是一个问题,我更新了它。我正在使用的 sqlite 库在 C 语言中很好。我正在从事Arduino项目,并且有cpp和c文件库。有时,我会有点混淆。
0赞 Adrian Mole 6/3/2023
@ManWithNoName 您在发布答案更改了语言标签 - 从而使我的答案无效。此外,您引用的错误消息仍然(非常清楚)来自 C++(而不是 C)编译器。Arduino编译器(IIRC)用作C++编译器。
0赞 ManWithNoName 6/3/2023
@AdrianMole好的,谢谢你的信息。Arduino IDE对我来说有点神秘。在此之前,我曾在 ASM 和 C 语言中从事 MPLAB IDE 的工作。有可能在微控制器上使用 C++ 中的对象对我来说是新的!
2赞 Adrian Mole 6/2/2023 #2

该行不声明指向对象的 2D 数组的指针;相反,它声明指向对象的指针的 2D 数组。String* str_array_ptr[100][10];StringString

声明指向 2D 数组的指针的语法很棘手;在您的例子中,它如下(声明为指向 100 x 10 对象数组的指针):str_array_ptrString

String (*str_array_ptr)[100][10];

投射到这样的指针(可以说)更加棘手;使用 C++(当源操作数为 时可以),您将获得以下代码:static_castvoid*

#include <iostream>
#include <string>
using String = std::string;

String str_array[100][10];

int callback(void* data) {

    String (*str_array_ptr)[100][10] = static_cast<String (*)[100][10]>(data);
    (*str_array_ptr)[0][0] = "text";
    return 0;
}

void test() {
    callback(&str_array);
}

有人可能会争辩说,如果你真的希望使用这样的指向 2D 数组的指针(C++ 中可能有更好的设计解决方案,例如 john 发布的答案),那么你可以用 or 语句为该指针定义类型(例如);然而,C++ 和 C 编程社区通常不赞成(严重而正确地)隐藏指针或别名。typedefusing...using StrArrPtrType = decltype(&str_array);typedefusing

评论

0赞 john 6/2/2023
尽管 OP 说他想要一个指向 2D 数组的指针,这就是你上面的内容。我认为这可能是 OP 方面的误解。可能他们只是想要一些有效的代码,并且比上面的代码中需要更多的间接级别。
0赞 Adrian Mole 6/2/2023
@john 是的,确实如此。我原本的意思是在我帖子的“更好的设计解决方案”部分引用您的答案(我现在已经这样做了)。