2015-10-20 92 views
2

我试图在TCL中构建一个测试框架,该框架允许我通过TCP套接字在远程设备上执行脚本测试。在Ubuntu中已经存在一个Visual Basic接口和SWIG,我正在重新使用它调用的C函数来构建一个共享库,它将作为TCL的扩展工作。我已经成功地使用SWIG的typemaps将基本函数(如打开/关闭套接字和基本读/写)合并到设备上的单个内存地址.i为readAddress函数提供指针(* OUTPUT),以将地址值返回给TCL 。使用SWIG将结构指针从TCL传递到C函数中

问题是,为了这个有用,我将不得不并入大量的远程过程调用,这些调用将复杂的数据类型传入(并退出!)设备。作为概念证明,我试图获得一个相对简单的功能。这试图通过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 
} 

我痛饮接口文件看起来像这样:

// 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以“创造”一个指针结构。

我有一种感觉,这是与海湾合作委员会做的事情,包括错误的顺序的文件,但我不知道下一步该怎么做。我已经尝试了在接口文件中的各个位置定义头部的多种组合,这是组合给出了最少的错误:​​)。你可以看到我的注释部分尝试使用typemaps而不是cpointers,但我对这些更加无知,我管理它的指向单个值的指针,但它似乎不适用于具有它自己的结构类型。它编译没有错误,但。

所以有可能得到我正在尝试使用cpointers.i工作吗?有关如何克服编译器问题的任何建议?我会更好地学习如何使用类型映射吗?让我知道在哪里可以提供更多详细信息,如果有帮助的话,我可能会遗漏关键信息,因为我必须总结和更改所有名称,因为这是公司的内容。

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

回答

0

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

但是,这可能是一个新问题,[在TCL中]使用新函数创建一个指针,将其馈送到rpc_testDefaults,并试图使用testDefaults_value取消引用所产生的指针只是返回另一个指针。我意识到,我不能只取消引用一个结构,但我不知道如何取消引用个别元素。我能找到的任何教程都只涉及解引用非结构体(而这些教程都不适用于TCL)。某处提到结构和传统知识部件之间有相似之处,所以我会仔细研究一下,但我仍然不确定我试图做甚么可能,而如果是这样,这是正确的方法做到这一点。

同样,我试图做的是在TCL中,访问已经通过指针从C函数返回的结构的单个元素。

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

+0

作为进一步的说明,移动%pointer_function(...到接口文件的底部排除了gcc编译问题。 – TheChizler