gpt4 book ai didi

python - 如何在 Python 中为类类型应用 SWIG OUTPUT 类型映射?

转载 作者:太空狗 更新时间:2023-10-29 18:34:05 25 4
gpt4 key购买 nike

我在使用 SWIG(版本 3.0.6)围绕 C++ 库生成 Python 包装器时遇到了一些问题。

我的问题与应用 OUTPUT 类型映射有关,特别是在类类型的指针/引用的情况下。

为了说明,这就是我想要的标准类型,并且它有效:

// .h
int add(const long arg1,const long arg2,long& resultLong);

// interface.i
%apply long& OUTPUT { long& resultLong };
int add(const long arg1,const long arg2,long& resultLong);

// projectWrapper.py
def add(arg1, arg2):
return _projectWrapper.add(arg1, arg2)
addTerm = _projectWrapper.add

// usage
>>> result = projectWrapper.add(2, 4)
>>> print result
[0, 6L]

您不必传入“resultLong”,但它会自动附加到结果中。太棒了!

但是,当输出类型是某个指向类类型的指针时,这似乎并没有像我预期的那样工作:

// .h
int GetClassType(const char* name, exportedClassType*& resultPointer);

class exportedClassType
{...}

// interface.i
%apply exportedClassType*& OUTPUT { exportedClassType*& resultPointer };
int GetClassType(const char* name, exportedClassType*& resultPointer);

// projectWrapper.py
def GetClassType(name, resultPointer):
return _projectWrapper.GetClassType(name, resultPointer)
GetClassType = _projectWrapper.GetClassType

问题好像是SWIG没有像simple类型那样处理。它仍然显示为包装函数签名中的“输入”参数。

// attempted usage
>>> classType = projectWrapper.GetClassType("name")
TypeError: GetClassType() takes exactly 2 arguments (1 given)

>>> result = 0
>>> projectWrapper.GetClassType("name", result)
Traceback (most recent call last):
File "<input>", line 1, in <module>
TypeError: in method 'GetClassType', argument 2 of type 'exportedClassType *&'

有人可以告诉我我做错了什么或指出正确的方向吗?任何帮助感激不尽!谢谢

最佳答案

这个问题已经有一段时间没有解决了,所以我想我最好提供一个解决问题的方法。 OUTPUT 类型映射仅适用于简单类型,因此通过组合 inargout 类型映射给出了解决方案。

考虑这样一种情况,我们有一个 C++ 类 SampleImpl 实现了一个 C++ 接口(interface) SampleBase,这在技术上不是一个接口(interface),因为它涉及到一个虚拟析构函数的实现.假设我们有一个静态函数,它返回错误代码和接口(interface)的实现。后者作为对指针的引用,也就是上面的情况。

接口(interface)标题:

// Sample.hpp
#pragma once
namespace Module {
class SampleBase {
public:
#ifndef SWIG
// Hint to the programmer to implement this function
static int SampleCreate(SampleBase *&obj);
#endif
virtual ~SampleBase() = default;
};
}

实现 header :

// Sample_impl.hpp
#pragma once
#include "Sample.hpp"

namespace Module {
class SampleImpl : public SampleBase {
public:
static int SampleCreate(Module::SampleBase *&obj);

SampleImpl();
virtual ~SampleImpl();
private:
float a;
};
}

实现:

// Sample_impl.cpp
#include "Sample_impl.hpp"
#include <cstdio>

namespace Module {
int SampleImpl::SampleCreate(Module::SampleBase*& obj) {
obj = (SampleBase*) new SampleImpl();
return 0;
}
SampleImpl::SampleImpl() {
printf("SampleImpl::SampleImpl()\n");
}

SampleImpl::~SampleImpl() {
printf("SampleImpl::~SampleImpl()\n");
}
}

SWIG 接口(interface)(使用 argout typemap)

// example.i
%module example
%{
#define SWIG_FILE_WITH_INIT
#include "Sample.hpp"
#include "Sample_impl.hpp"
%}

%include "typemaps.i"

%typemap(in, numinputs=0) Module::SampleBase *&obj (Module::SampleBase *temp) {
$1 = &temp;
}

%typemap(argout) Module::SampleBase *& {
PyObject* temp = NULL;
if (!PyList_Check($result)) {
temp = $result;
$result = PyList_New(1);
PyList_SetItem($result, 0, temp);

// Create shadow object (do not use SWIG_POINTER_NEW)
temp = SWIG_NewPointerObj(SWIG_as_voidptr(*$1),
$descriptor(Module::SampleBase*),
SWIG_POINTER_OWN | 0);

PyList_Append($result, temp);
Py_DECREF(temp);
}
}

Python 中的用法

import example

// Creating specialization
obj = example.SampleImpl()
del obj

// Creation of object using output typemap
errorCode, obj = example.SampleImpl_SampleCreate()
del obj

关于python - 如何在 Python 中为类类型应用 SWIG OUTPUT 类型映射?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/32478649/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com