2015-10-20 93 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