c - 使用 SWIG 将指向结构的指针从 TCL 传递到 C 函数

标签 c pointers gcc struct swig

我正在尝试在 TCL 中构建一个测试框架,它允许我通过 TCP 套接字在远程设备上执行脚本测试。在 Ubuntu 中已经存在一个 Visual Basic 界面和 SWIG,我正在重用它调用的 C 函数来构建一个共享库,该库将作为 TCL 的扩展。我已经成功地整合了基本功能,例如打开/关闭套接字,以及使用 SWIG 的类型映射对设备上的单个内存地址进行基本读/写。我提供指向 readAddress 函数的指针(*OUTPUT)以将地址值返回给 TCL .

问题是,为了使它有用,我将不得不合并大量远程过程调用,这些远程过程调用将复杂的数据类型传递到(并返回!)设备。作为概念证明,我试图让一个相对简单的函数起作用。这会尝试通过 RPC 读取默认测试参数;为用于结果的函数提供了指向结构的指针:rpc_testDefaults ( testDefaults_t *testDefaults )

testDefaults_t 的类型定义在 testDefaults.h 中,其样式如下:

// testDefaults.h
#include <stdint.h>

typedef uint32_t   customType_t;

typedef struct
{
    customType_t   varName1;    // Description
    uint32_t       varName2;    // Description

    // 13 more uint32_t elements

} testDefaults_t;

// Two more struct type definitions

testDefaults.c 是这样的:

// testDefaults.c
#include "testDefaults.h"

// #ifdefs to compile as 'client' OR 'server' (defaults to 'client')

rpc_testDefaults ( testDefaults_t, *testDefaults )
{
    // function
}

我的 SWIG 接口(interface)文件如下所示:

// rpcTest.i
%module rpcTest
%include <cpointer.i>
%include "testDefaults.h"
%pointer_functions(testDefaults_t, testDefaults);
//%apply int *OUTPUT {testDefaults_t, *testDefaults};

%{
    #include "testDefaults.h"
    extern int rpc_testDefaults ( testDefaults_t, *testDefaults )
}%

extern int rpc_testDefaults ( testDefaults_t, *testDefaults )

在同一个文件夹中还有许多其他支持此功能的 .c 和头文件以及我提到的其他我正在使用的文件。

我运行 swig -tcl -debug-typedef rpcTest.i 得到 rpcTest_wrap.c,我可以看到 testDefaults_t 已被识别为类型/范围,因为在调试输出(它也包含在未命名范围部分:testDefaults_t -> testDefaults_t)。

我运行 gcc -fPIC -DCLIENT_FLAG -c *.c -I/usr/include/tcl8.5 并从 SWIG 输出文件中的一行中得到错误:rpcTest_wrap .c:1803:3: error: unknown type name 'testDefaults_t' (加上由此产生的更多错误)。有问题的行是此函数的第一行:

static testDefaults_t *new_testDefaults() {
    return (testDefaults_t *)malloc(sizeof(testDefaults_t));
}

我认为这是 cpointers.i 为 TCL 创建一个函数来“创建”指向该结构的指针。

我感觉这与 gcc 以错误的顺序包含文件有关,但我不知道下一步该怎么做。我尝试了多种在接口(interface)文件的不同位置定义 header 的组合,这种组合给出的错误最少 :)。您可以看到我已注释掉的部分尝试使用类型映射而不是指针,但我对这些更无能为力,我管理它是为了指向单个值的指针,但它似乎不适用于具有它自己的结构类型。不过它确实编译没有错误。

那么是否有可能使用 cpointers.i 实现我正在努力实现的工作?关于如何克服编译器问题的任何建议?学习如何使用类型映射会更好吗?如果有帮助,请告诉我在哪里可以提供更多详细信息,我可能会遗漏重要信息,因为我不得不总结并更改所有名称,因为这是公司的事情。

任何帮助/批评将不胜感激!

最佳答案

查看 rpcTest_wrap.c 文件,我注意到 testDefaults.h 的包含就在试图使用它的函数组之后。我用 testDefaults_t 替换了接口(interface)文件中的“int”(我认为这是正确的),运行 SWIG,编辑输出(我知道这很危险!)以便 include 发生在这些函数之前,并且编译正常。我可以将共享库加载到 TCL 中并运行新函数。

然而,这可能是一个新问题,[在 TCL 中] 使用新函数创建一个指针,将其提供给 rpc_testDefaults,并尝试使用 testDefaults_value 取消引用结果指针只会返回另一个指针。我意识到我不能只取消引用一个结构,但我不知道如何取消引用单个元素。我能找到的任何教程都只涉及取消引用非结构(这些教程都不是针对 TCL 的)。某处提到结构和 TK 小部件之间存在相似之处,因此我将对此进行研究,但我仍然不确定我正在尝试做的事情是否可行,如果是这样,这是否是正确的方法做吧。

同样,我尝试做的是在 TCL 中,访问通过指针从 C 函数返回(或馈入)的结构的各个元素。

更新:我最终通过使用我在包装文件末尾发现的 SWIG 生成的函数来完成这项工作。 cpointer.i 根本不需要。在 TCL 中,我首先使用新函数 new_testDefaults 创建一个指针,该函数以 TCL 样式指针的形式返回一个字符串。我将这个指针传递给 rpc_testDefaults,它什么都不返回,因为它实际上是一个 void 函数。然后,我可以通过将上述指针设置为 SWIG 生成的 elementName_get 和 elementName_set 函数的参数来访问上述指针引用的结构中的各个元素。下一个任务是让更复杂的函数工作,结构中的结构等,但现在我已经熟悉了方法,应该不会太难。

关于c - 使用 SWIG 将指向结构的指针从 TCL 传递到 C 函数,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/33233641/

相关文章:

c - 为什么 GCC 说一个变量在未使用时未使用?

c - c/c++ 中的 gcc 编译器是否保证将指向 const 数据的全局 const 指针放置在单独的只读部分中?

c - 如何将句子扫描到字符串数组中?

我可以从 SD 存储器而不是闪存在评估板上运行程序(嵌入式编程)吗?

c - const struct pointer 是否保证内存损坏/崩溃问题的安全性?

C - 带指针的函数的段错误

可执行文件中的C语言变量

c++ - 共享库或 dylib 中 undefined symbol 的处理方式是什么?

c - 使用内联汇编在 C 中添加值

c++ - OpenCV/C++ - 如何释放指针