簡體   English   中英

在 SWIG 中從 C++ 到 Python 獲取 char* output

[英]Getting a char* output from C++ to Python in SWIG

我正在嘗試創建一個 Python 藍牙包裝器來包裝 C++ 類。 這是我的 SWIG 接口文件:

%module blsdk


%include "pyabc.i"
%include "std_vector.i"
%include "cstring.i"
%include "cpointer.i"
%include "typemaps.i"

%include serialport.i
%include exploresearch.i

這是我的serialport.i

%module  serialport

%{
#include <string>

#include <stdio.h>
#include <errno.h>
#include <fcntl.h>
#include <unistd.h>
#include <stdlib.h>
#include <signal.h>
#include <termios.h>
#include <sys/poll.h>
#include <sys/ioctl.h>
#include <sys/socket.h>
#include <sys/types.h>
#include <assert.h>

#include <bluetooth/bluetooth.h>
#include <bluetooth/hci.h>
#include <bluetooth/hci_lib.h>
#include <bluetooth/sdp.h>
#include <bluetooth/sdp_lib.h>
#include <bluetooth/rfcomm.h>

#include "BTSerialPortBinding.h"
%}

%include "BTSerialPortBinding.h"

我的 BTSerialPortBinding.h 具有以下功能:

static BTSerialPortBinding *Create(std::string address, int channelID);

int Connect();

void Close();

int Read(char *buffer, int length);

void Write(const char *write_buffer, int length);

bool IsDataAvailable();

如何包裝int Read(char* buffer, int length) function? 我想將 char* 緩沖區作為 output 並將長度作為輸入。 I have tried to define the read function as int Read(char* OUTPUT, int length) but this gives an error: TypeError: a bytes-like object is required, not 'str' in my program as I need a byte object in Python . 任何幫助將不勝感激。

這不是一個完整的答案,但它可能會讓你開始四處亂竄。 與 SWIG 一樣,關鍵是查看生成的代碼並對其進行修改。 再次寫下我的頭頂,只是一個起點。

您可以做的一件事是有點 hacky,但如果您對讀取的數據量有一些理論上的限制,則可以工作。 一種方便的方法是使用這樣的一對“吞下”輸入和返回值:

%typemap(in,numinputs=0) char *buffer
{
    $1 = malloc(some_arbitrary_large_amount);
    // or 'cheat' by looking at swig output and using the value you just happen
    // to know is the length (like arg1 or something)
}

%typemap(argout) char *buffer
{
    PyObject *tmp = $result;
    int len = 0;
    int res = SWIG_AsVal_long(tmp, &len);
    if(!SWIG_IsOK(res)) {
        free($1);
        SWIG_fail;
    }
    $result = SWIG_From_CharPtrAndSize( $1, len );
    PyDecRef(tmp); //probably?
    free($1);
}

這會將 python 端的接口更改為僅采用長度參數並返回 python 字符串,這可能不是您想要的。 請注意,您可以返回您喜歡的任何內容,而不是 SWIG_From_CharPtr,您可以創建一些其他的 python object,如字節數組。

另一種方法是使用多參數類型映射。 這里的細節更加模糊,但你會做類似的事情:

%typemap(in) (char *buffer, int length)
{
/*
$input is a python object of your choice - bytearray?
Use the various Python/Swig APIs to decode the input object.
Set $1 and $2 to the data pointer and length decoded from
your input object and they will be passed to the C function.
*/
}

現在你在 python 端有一個 Read() function ,它接受一個參數,由你來創建和設置大小。 只要您能弄清楚如何訪問內部數組和大小,就可以是任何東西。 Numpy 是一個不錯的候選者,但如果您使用的是 Numpy,他們已經為 SWIG 提供了一組非常好的類型圖。 然后你就這樣做:

%include "numpy.i"
%apply( char *IN_ARRAY1, int DIM1 )

並給它一個 numpy 陣列。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM