![](/img/trans.png)
[英]Calling a C function from Python generated by SWIG, with 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.