Простой класс C++ для переноса представлен следующим образом: заголовочный файл.
example6.h
Код: Выделить всё
#pragma once
class Message
{
private:
uint8_t * m_data;
int m_size;
public:
Message( void )
: m_data( NULL )
, m_size( 0 )
{
m_data = new uint8_t[3]();
m_data[0] = 'A';
m_data[1] = 'B';
m_data[2] = 'C';
m_size = 3;
}
virtual ~Message( void )
{
delete[] m_data;
}
int package( uint8_t** buf )
{
*buf = NULL;
int size = 0;
if ( m_data )
{
*buf = m_data;
size = m_size;
}
return size;
}
};
example6.swg
Код: Выделить всё
%module example6
%{
#define SWIG_FILE_WITH_INIT
#include "example6.h"
%}
%typemap( in, numinputs=0 ) ( uint8_t** buf )
{
uint8_t** temp = 0x0;
$1 = temp;
}
%typemap( argout ) ( uint8_t** buf )
{
if ( *$1 )
{
$result = PyBytes_FromString( (char *)( *$1 ) );
free( *$1 );
}
}
%include "example6.h"
Я не уверен, какой тип переменной Python предоставить в качестве аргумента для метода Message.package() при его вызове. . Я думаю, мне нужно, чтобы переменная имела тип байт. Или, может быть, мне нужны дополнительные директивы %typemap для правильного преобразования переменной Python bytes в переменную C++ uint8_t**?
Ниже: демонстрация проблемы.
Код: Выделить всё
finch@laptop:~/work/swig_example$ python3
Python 3.10.12 (main, Nov 20 2023, 15:14:05) [GCC 11.4.0] on linux
Type "help", "copyright", "credits" or "license" for more information.
>>> import example6
>>> m = example6.Message()
>>> b = bytes()
>>> b
b''
>>> m.package( b )
Traceback (most recent call last):
File "", line 1, in
File "/home/finch/work/swig_example/example6.py", line 73, in package
return _example6.Message_package(self, buf)
TypeError: in method 'Message_package', argument 2 of type 'uint8_t **'
example6_wrap.cxx
Код: Выделить всё
SWIGINTERN PyObject *_wrap_Message_package(PyObject *SWIGUNUSEDPARM(self), PyObject *args) {
PyObject *resultobj = 0;
Message *arg1 = (Message *) 0 ;
uint8_t **arg2 = (uint8_t **) 0 ;
void *argp1 = 0 ;
int res1 = 0 ;
void *argp2 = 0 ;
int res2 = 0 ;
PyObject *swig_obj[2] ;
int result;
if (!SWIG_Python_UnpackTuple(args, "Message_package", 2, 2, swig_obj)) SWIG_fail;
res1 = SWIG_ConvertPtr(swig_obj[0], &argp1,SWIGTYPE_p_Message, 0 | 0 );
if (!SWIG_IsOK(res1)) {
SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "Message_package" "', argument " "1"" of type '" "Message *""'");
}
arg1 = reinterpret_cast< Message * >(argp1);
res2 = SWIG_ConvertPtr(swig_obj[1], &argp2,SWIGTYPE_p_p_uint8_t, 0 | 0 );
if (!SWIG_IsOK(res2)) {
//*** Finch temp: This is where the TypeError exception will be raised.
SWIG_exception_fail(SWIG_ArgError(res2), "in method '" "Message_package" "', argument " "2"" of type '" "uint8_t **""'");
}
arg2 = reinterpret_cast< uint8_t ** >(argp2);
result = (int)(arg1)->package(arg2);
resultobj = SWIG_From_int(static_cast< int >(result));
//*** Finch temp: This is the snippet that the %typemap(argout) directive injects.
{
if ( *arg2 )
{
resultobj = PyBytes_FromString( (char *)( *arg2 ) );
free( *arg2 );
}
}
//***
return resultobj;
fail:
return NULL;
}
Какая карта типов поможет мне преобразовать переменную Python bytes в переменную C++ uint8_t**.
Проблема 2
Код: Выделить всё
PyBytes_FromString()Если нет, уместно ли для директивы %typemap(argout) иметь много более сложного кода, такого как итерация байтового буфера и ручное копирование его в... что-то еще?
Я искал и собирал примеры из несколько мест, в том числе:
- Как применить карту типов SWIG для аргумента структуры с двойным указателем
- SWIG Python — упаковка функция, которая ожидает двойной указатель на структуру.
- SWIG возвращает байты вместо строки с картой типов.
- карта типов Swig для Python: входные и выходные массивы< /li>
Как применить карту типов SWIG _только_ к определенной функции? - SWIG 'cstring.i' Python возвращает байтовый тип вместо строкового типа
- li>
https://docs.python.org/3.10/c-api/bytearray.html - https://docs.python.org/3.10 /c-api/bytes.html
Подробнее здесь: https://stackoverflow.com/questions/790 ... using-swig