创建一个适用于 C++ 重载函数的 SWIG 类型映射

我想知道如何为重载函数创建 SWIG 类型映射。

MyBindings.h

static void test(t_string *s)
{
    std::cout << "first : " << s->name << '\n');
}

static void test(t_string *s, t_string *s2)
{
    std::cout << "first : " << s->name << '\n');
    std::cout << "second : " << s2->name << '\n');
}

MyBindings.i

%module my
%{
    #include "MyBindings.h"
%}

%include <stl.i>
%include <exception.i>
%include <typemaps.i>
/* 将输入的 lua_String 转换为 t_string* */
%typemap(in) t_string*
{
    if (!lua_isstring(L, $input))
        SWIG_exception(SWIG_RuntimeError, "argument mismatch: string expected");
    $1 = makestring(lua_tostring(L, $input));
}

然后如果我在 Lua 中调用 test()

my.test("abc", "def");

我会得到以下错误:

Wrong arguments for overloaded function 'test'
  Possible C/C++ prototypes are:
    test(t_string *)
    test(t_string *,t_string *)

我应该如何修正我的类型映射以使其正常工作?

点赞
用户1944004
用户1944004

这是一个典型的 RTFM 情况。请参见 11.5.2 "typecheck" typemap

如果您定义了新的“in”类型映射 并且 您的程序使用了重载方法,您还应该定义一组“typecheck”类型映射。关于此更多详细信息,请参见 Typemaps and overloading 部分。

和你以往的问题一样,在你的头文件中缺少引用保护(include guards)。我只是创建了自己的 t_string.h,因为我不知道这个是从哪里来的。函数test不能是静态的,因为你想从这个翻译单元外面引用它们,而当它们具有内部链接时这是不可能的。

MyBindings.h

#pragma once
#include <iostream>
#include "t_string.h"

void test(t_string *s)
{
    std::cout << "first : " << s->name << '\n';
}

void test(t_string *s, t_string *s2)
{
    std::cout << "first : " << s->name << '\n';
    std::cout << "second : " << s2->name << '\n';
}

MyBindings.i

%module my
%{
    #include "MyBindings.h"
%}

/* 将输入的 lua_String 转换为 t_string* */
%typemap(typecheck) t_string* {
    $1 = lua_isstring(L, $input);
}
%typemap(in) t_string* {
    $1 = makestring(lua_tostring(L, $input));
}
%typemap(freearg) t_string* {
    freestring($1);
}
%include "MyBindings.h"

test.lua

local my = require("my")
my.test("abc", "def")

示例调用:

$ swig -c++ -lua MyBindings.i
$ clang++ -Wall -Wextra -Wpedantic -I /usr/include/lua5.2 -shared -fPIC MyBindings_wrap.cxx -o my.so -llua5.2
$ lua5.2 test.lua
first : abc
second : def
2018-08-02 11:08:34