痛饮:“走出去”的类型表结构字段需要访问相同结构的另一场

问题描述 投票:6回答:2

我试图换一个C库(我没写,并且其接口不能更改)使用痛饮。这主要是简单的,但是有一个struct多数民众赞成给我的麻烦的一个领域。相关struct定义是这样的:

struct Token {
    const char *buffer;
    const char *word;
    unsigned short wordlen;
    // ... other fields ...
};

buffer是一个普通的C串和通常应(但不可改变)露出。 word的问题领域。它是一个指向buffer串内的某处,并旨在被理解为长度wordlen的字符串。我要揭露这个高层次的语言作为一个正常的只读字符串,因此他们并不总是必须要采取一个切片。

我认为处理这种方式是专门为Token::word,像这样的“出”类型表:

struct Token {
    %typemap (out) const char *word {
        $result = SWIG_FromCharPtrAndSize($1, ?wordlen?);
    }
}

而这正是我卡住了:我怎么访问父结构的wordlen领域从这个类型映射?

或者,如果有更好的方法来处理这整个问题,请告诉我有关吧。

c swig
2个回答
0
投票

不幸的是,它看起来像呷有同时映射多个结构成员的支持。检查所产生的输出,我们得知(arg1)指向输入结构。因此,我们必须:

  1. 使word不变的,所以不产生set包装。
  2. 导入SWIG_FromCharPtrAndSize片段 - 这不是默认情况下可用。
  3. 使用word你愿意,指SWIG_FromCharPtrAndSize地图(arg1)->wordlen
  4. 跳过wordlen,因此,它不是映射(通过%ignore-ING它,否则无法在struct痛饮可见提供的话)。

下面是一个完整的例子。首先,头:

// main.h
#pragma once

struct Token {
  const char *word;
  unsigned short wordlen;
};

struct Token *make_token(void);
extern char *word_check;

而SWIG模块 - 请注意,我们使用的标题一字不差,只覆盖struct Token的定义:

// token_mod.i
%module token_mod
%{#include "main.h"%}
%ignore Token;
%include "main.h"
%rename("%s") Token;

struct Token {
  %immutable word;
  %typemap (out, fragment="SWIG_FromCharPtrAndSize") const char *word {
    $result = SWIG_FromCharPtrAndSize($1, (arg1)->wordlen);
  }
  const char *word;
  %typemap (out) const char *word;
};

使用Python来检查工作的事情演示代码:

// https://github.com/KubaO/stackoverflown/tree/master/questions/swig-pair-53915787
#include <assert.h>
#include <stdlib.h>
#include <Python.h>
#include "main.h"

struct Token *make_token(void) {
  struct Token *r = malloc(sizeof(struct Token));
  r->word = "1234";
  r->wordlen = 2;
  return r;
}

char *word_check;

#if PY_VERSION_HEX >= 0x03000000
#  define SWIG_init    PyInit__token_mod
PyObject*
#else
#  define SWIG_init    init_token_mod
void
#endif
SWIG_init(void);

int main()
{
   PyImport_AppendInittab("_token_mod", SWIG_init);
   Py_Initialize();
   PyRun_SimpleString(
            "import sys\n"
            "sys.path.append('.')\n"
            "import token_mod\n"
            "from token_mod import *\n"
            "token = make_token()\n"
            "cvar.word_check = token.word\n");
   assert(word_check && strcmp(word_check, "12") == 0);
   Py_Finalize();
   return 0;
}

最后,使演示的CMakeLists.txt - 可以使用Python 2.7或3.x中使用注意:要切换的Python版本,build目录必须被消灭(或至少在它CMake的缓存必须擦拭)。

cmake_minimum_required(VERSION 3.2)

set(Python_ADDITIONAL_VERSIONS 3.6)
project(swig-pair)
find_package(SWIG 3.0 REQUIRED)
find_package(PythonLibs 3.6 REQUIRED)
include(UseSwig)

SWIG_MODULE_INITIALIZE(${PROJECT_NAME} python)
SWIG_ADD_SOURCE_TO_MODULE(${PROJECT_NAME} swig_generated_sources "token_mod.i")
add_executable(${PROJECT_NAME} "main.c" ${swig_generated_sources})
target_include_directories(${PROJECT_NAME} PRIVATE ${PYTHON_INCLUDE_DIRS} ".")
target_link_libraries(${PROJECT_NAME} PRIVATE ${PYTHON_LIBRARIES})

-1
投票

更高层次的语言不在乎wordlen是字的大小。只有C一样。如果你不能改变你是swiging那么C你要保留原样,并记住,你在该字符的大小更高的语言编写。还痛饮和const不喜欢对方。 Hereis那里consts文档

© www.soinside.com 2019 - 2024. All rights reserved.