2011-11-17 63 views
4

我在SWIG中使用Python中的C++函數,現在我遇到了一個問題。 當我將C++中的char *傳遞給Python時,char *被Python截斷。Python如何通過SWIG從C++獲取二進制數據(char *)?

例如:

example.h文件:

char * fun() 
{ 
    return "abc\0de"; 
} 

現在在Python中,我們稱之爲 example.fun() 只打印 「ABC」 而不是 「ABC \ 0de 「 '\ 0'後面的數據被Python刪除。

我想所有的字符從樂趣()在C++中, 和任何意見(它是一個可以包含一個二進制數據「\ 0」)表示讚賞

+0

相反的情況(通過二進制數據** **到C/C++)是公由文檔所覆蓋。 (你的問題沒有覆蓋AFAIK)。 http://www.swig.org/Doc3.0/Library.html#Library_nn10 –

回答

6

C/C++字符串以NULL結尾,這意味着第一個\0字符表示字符串的結尾。

當函數返回一個指針,這樣的字符串,調用者(SWIG在這種情況下)沒有辦法知道是否有第一\0經過數據的方式,使這就是爲什麼你只得到了第一部分。

所以首先要做的是改變你的C函數,不僅返回字符串,而且還返回它的長度。由於只能有一個返回值,我們將使用指針參數。

void fun(char** s, int *sz) 
{ 
    *s = "abc\0de"; 
    *sz = 6; 
} 

的SWIG文檔建議使用cstring.ilibrary包裹這樣的功能。特別是,最後一個宏確實是你所需要的。

%cstring_output_allocate_size(parm, szparm, release) 

閱讀the docs瞭解如何使用它。

+0

對不起,我的英語不好(哈哈,我是中國人),你幫助我解決了困擾我整整一週的問題。非常感謝你~~~ – kaitian521

0

8.3 C String Handling的文件中。

同樣來自documentation

的炭*數據類型爲NULL結尾的ASCII字符串處理。 SWIG 將其映射爲目標腳本 語言中的8位字符串。在將它們傳遞到C/C++之前,SWIG將目標語言中的字符串轉換爲NULL結尾的字符串。處理這些字符串的默認 不允許它們嵌入NULL 字節。因此,char *數據類型通常不適用於傳遞二進制數據的 。但是,可以通過定義SWIG類型映射來更改此行爲 。有關詳細信息,請參閱關於類型映射的章節 。

+0

非常感謝你,計算器是如此之大~~~ – kaitian521

7

首先,如果你正在處理的二進制數據(痛飲認爲他們是普通字符串),你不應該使用char *。相反,你應該使用void *。 swig提供了一個名爲'cdata.i'的模塊 - 您應該將其包含在接口定義文件中。

一旦你有這種情況,給出了兩個功能 - cdata()memmove()

  • 給定一個void *和二進制數據的長度,cdata()將其轉換成字符串類型的目標語言的。
  • memmove()做相反 - 給定的一個字符串類型,它將字符串(包括嵌入的空字節)的內容複製到C void*類型。

處理二進制數據成爲該模塊簡單得多。我希望這是你所需要的。

example.i 
%module example 
%include "cdata.i" 
%{ 
void *fun() 
{ 
     return "abc\0de"; 
} 
%} 

test.py 
import example 
print example.cdata(example.fun(), 6) 
+1

你能不能也給如何使用'的memmove()'的例子嗎? –

相關問題