我正在尝试创建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
这是我的串口。
%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 *缓冲区,int长度)函数?我想将char *缓冲区作为输出,并将长度作为输入。我试图将读取函数定义为int Read(char * OUTPUT,int length),但这给出了一个错误:TypeError:需要一个类似字节的对象,而不是'str'因为我需要Python中的字节对象。任何帮助将不胜感激。
这不是一个完整的答案,但它可能有助于您开始黑客入侵。与SWIG一样,关键是查看生成的代码并四处寻找。再次写下我的头顶,只是一个起点。
您可以做的一件事情有点棘手,但是如果您对读取的数据量有一定的理论限制,则可以使用。一种方便的方法是用这样的一对“吞噬”输入和返回值:
%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
{
$result = SWIG_From_CharPtrAndSize( $1, $result );
free($1);
}
这会更改python一侧的接口,使其仅使用length参数并返回一个可能不是您想要的python字符串。请注意,您可以返回所需的任何内容,因此可以代替SWIG_From_CharPtr来创建其他一些python对象,例如字节数组。
另一种方法是使用多参数类型映射。这里的细节比较模糊,但是您会做类似的事情:
%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()函数,该函数接受一个参数,该参数由您决定是否创建和设置其大小。只要您能弄清楚如何访问内部数组和大小,都可以。 Numpy是一个很好的候选人,但是如果您使用的是Numpy,他们已经拥有一套非常不错的SWIG类型映射。然后,您只需执行以下操作:
%include "numpy.i"
%apply( char *IN_ARRAY1, int DIM1 )
并为其提供一个numpy数组。