Оболочка Swig для функции с другим указателем структуры

Я хочу обернуть следующую функцию C. Обратите внимание, приведение типа от Foo_t * к Bar_t *:

void function(Foo_t * f) {
      Bar_t * b = (Bar_t *) f;  // casting is done in C original code
      //do sth with b
}

Swig создает оболочку, которая следует следующему шаблону:

void wrap_function( Foo_t *foo ) {
     function(foo);
}

Но в python я хочу вызвать свою функцию-оболочку, используя экземпляр Bar_t:

b = Bar_t()
function(b) 

Итак, я начал следующую карту типов:

%typemap(in) Foo * {
  Bar_t *temp;
  int res0 = 0;
  Foo_t *arg = 0;

  res0 = SWIG_ConvertPtr($input, (void **) &temp, $descriptor(Bar_t *), 0|0);
    if (!SWIG_IsOK(res0)) {
        SWIG_exception_fail(SWIG_ArgError(res0), "in method '" "function" "', argument " "1"" of type '" "Bar_t *""'"); 
    } 
     $1 = (Foo_t *) temp;
     function(arg);
}

Но выбрасывается исключение!

Как я могу преобразовать Bar_t * в Foo_t *?

Доступ через указатель другого типа является поведением undefined. Используйте C++, если вам нужно наследование.

Henri Menke 07.02.2019 23:14

Если требования к выравниванию одинаковы для Foo * и Bar *, я должен получить исходный указатель. Я не могу изменить сторону кода C.

pablomtz 08.02.2019 12:26
Почему в Python есть оператор "pass"?
Почему в Python есть оператор "pass"?
Оператор pass в Python - это простая концепция, которую могут быстро освоить даже новички без опыта программирования.
Некоторые методы, о которых вы не знали, что они существуют в Python
Некоторые методы, о которых вы не знали, что они существуют в Python
Python - самый известный и самый простой в изучении язык в наши дни. Имея широкий спектр применения в области машинного обучения, Data Science,...
Основы Python Часть I
Основы Python Часть I
Вы когда-нибудь задумывались, почему в программах на Python вы видите приведенный ниже код?
LeetCode - 1579. Удаление максимального числа ребер для сохранения полной проходимости графа
LeetCode - 1579. Удаление максимального числа ребер для сохранения полной проходимости графа
Алиса и Боб имеют неориентированный граф из n узлов и трех типов ребер:
Оптимизация кода с помощью тернарного оператора Python
Оптимизация кода с помощью тернарного оператора Python
И последнее, что мы хотели бы показать вам, прежде чем двигаться дальше, это
Советы по эффективной веб-разработке с помощью Python
Советы по эффективной веб-разработке с помощью Python
Как веб-разработчик, Python может стать мощным инструментом для создания эффективных и масштабируемых веб-приложений.
1
2
159
1
Перейти к ответу Данный вопрос помечен как решенный

Ответы 1

Ответ принят как подходящий

Если вы создадите карту типов, ожидающую оболочку Python Bar_t для ввода Foo*, вы не сможете передать Foo* вводу Foo*. Вместо этого экспортируйте помощник приведения. Обратите внимание, что нотация %inline реализует и экспортирует оболочку для содержимого.

тест.ч

#ifdef _WIN32
#   ifdef EXPORT
#       define API __declspec(dllexport)
#   else
#       define API __declspec(dllimport)
#   endif
#else
#   define API
#endif

typedef struct Foo {
    int a;
} Foo_t;

typedef struct Bar {
    int b;
} Bar_t;

API void function(Foo_t * f);

тест.с

#define EXPORT
#include <stdio.h>
#include "test.h"

API void function(Foo_t * f) {
      Bar_t * b = (Bar_t *) f;  // casting is done in C original code
      // do something with b
}

тест.i

%module test

%{
#include "test.h"
%}

%inline %{
Foo_t* Foo_cast(Bar_t* bar) {
    return (Foo_t*)bar;
}
%}

%include "test.h"

Тестирование:

>>> import test
>>> bar = test.Bar_t()
>>> test.function(test.Foo_cast(bar))
>>> foo = test.Foo_t()
>>> test.function(foo)
>>>

Другие вопросы по теме