如何将Sigg TypeMap仅应用于特定函数? [英] How do I apply a SWIG typemap to _only_ a specific function?

查看:15
本文介绍了如何将Sigg TypeMap仅应用于特定函数?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

假设我有一个要为其应用特殊类型映射的函数(因为它以字符数组的形式返回二进制数据)。

const char* returnBinaryData( int arg1, int arg2, size_t ret_length );

因为有其他具有相同返回类型的函数是我不想触及的。

const char* getName( int arg1, int arg2 );

是否有方法将(out)类型映射应用于特定函数(使用其名称,而不是其参数列表)?

(我正在对Python使用SWIG。)

更新:针对类

其中一个复杂的因素是我要包装的函数是一个类方法。

将其视为定义。

class A {
public:
    char datum[16];
    char name[32];
    A( int32_t seed ) : name("sample name") {
        for (int i=0;i<16;i++) datum[i] = static_cast<char>(((i*i+seed) % 64) + '0');
    }
    const char* getName() {
        return name;
    }
    const char* getBinaryData( int32_t arg1, int32_t length ) {
        auto s = new char[length];
        for (int i=0;i<length;i++) s[i] = datum[(arg1 + i) % sizeof(datum)];
        return s;
    }
};

需要更改什么才能将包装重命名为类方法?

我尝试确定重命名操作的作用域,但它生成的包装器代码没有执行我想要的操作。(AFAICT,文档对此并不完全清楚。)

推荐答案

我使用了包装函数,并为特殊情况创建了自定义类型映射:

Test.i

%module test

%{
const char* getName(int arg1, int arg2) {
    static char s[] {"something"};
    return s;
}

const char* returnBinaryData(int arg1, int arg2, size_t ret_length) {
    auto s = new char[ret_length];
    for(size_t i = 0; i < ret_length; ++i)
        s[i] = static_cast<char>(i % 256);
    return s;
}

// wrapper to allow custom typemap
void mygetbin(int arg1, int arg2, size_t length, const char** output) {
    *output = returnBinaryData(arg1, arg2, length);
}
%}

%include <exception.i>

// Input typemap that expects a Python integer input for this precise pair of parameters
%typemap(in) (size_t length, const char** output) (char* out = nullptr) %{
    $2 = &out;
    if(!PyLong_Check($input))
        SWIG_exception(SWIG_TypeError, "expected integer");
    $1 = PyLong_AsUnsignedLongLong($input);
%}

// A Python bytes object will be returned that Python will manage,
// so free the C++ allocation to prevent a memory leak.
%typemap(freearg) (size_t length, const char** output) %{
    delete[] *$2;
%}

// Append the output argument to the return value.
%typemap(argout) (size_t length, const char** output) %{
    $result = SWIG_Python_AppendOutput($result, PyBytes_FromStringAndSize(*$2, $1));
%}

%ignore returnBinaryData; // necessary if getName and returnBinaryData included via %include "someheader.h"

// Process this function normally with default handling of char* output.
// This could be %include "someheader.h" instead, and all the functions would be swigged except
// for the ignored function.
const char* getName(int arg1, int arg2);

// Explicitly rename the wrapper and process it.
%rename(returnBinaryData) mygetbin;
void mygetbin(int arg1, int arg2, size_t length, const char** output);

演示:

>>> import test
>>> test.getName(1,2)
'something'
>>> test.returnBinaryData(1,2,10)
b'x00x01x02x03x04x05x06x07x08	'

这篇关于如何将Sigg TypeMap仅应用于特定函数?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆