SWIG / Python:将指针传递给函数

时间:2016-05-18 17:09:21

标签: python c swig handle void-pointers

我基本上想要做到这一点:

swig: how to pass void* into generic function

我似乎能够获得Python可以容纳的值,但是当我将其传回时,它被视为null并导致失败。所以我想我需要某种PyObject转换。我不知道为什么void指针应该很难处理。

(我实际上是在和HMODULE一起工作,但我想如果我能得到无效的工作指针,我也可以让他们工作。

基本上,我只想:

>>hmod = example.load_module("fooModName")
>>example.run_module(hmod, par1, par2)

如何定义输入和输出类型图,以便支持这两个调用?

我正在尝试使用HMODULE(在Windows.h中定义,最终作为void指针)

HMODULE load_library(char *pathDLL);
int     get_api(HMODULE dll);   // loads/updates api

=============================================== ============

我已经弄明白了我的实际问题。

包裹时的惯例是:

>>ModuleName = example.find_module_name("lookDir")
>>HModule = example.load_module(ModuleName)

问题是返回的名称是char字符串(char *),但LoadLibrary()MSDN例程需要LPCWSTR。我可以很容易地在例程中转换字符串,但是它会将其分解以供其他用途,所以我真的想在输入包装器中转换字符串。

我认为解决方案是某种类型的类型图。

我正在尝试这个:

%typemap(in) char* inpathDLL {
static wchar_t LpathDLL[2048];
MultiByteToWideChar(CP_ACP, 0, $input, -1, LpathDLL, 2048);
$1 = LpathDLL;
}

这是失败的。似乎输入是一个python字符串对象,所以我不得不让它在应用下一次转换之前将它转换为char *。

如何转换此输入字符串?

解答:

好的,我发现了(?)修复。诀窍是使用'check',在默认转换后添加代码:

%typemap(check)char* inpathDLL {
  if ($1 != NULL) {
    static wchar_t LpathDLL[2048];
    MultiByteToWideChar(CP_ACP, 0, $1, -1, LpathDLL, 2048);
    $1 = (char *)LpathDLL;
  }
}

1 个答案:

答案 0 :(得分:2)

Swig直接支持该用法,不需要任何类型地图。

让代码段工作的一种方法如下:

/* File : example.c */

void *
load_module(const char* name)
{
    static int module_handle = 12;
    printf("Hoory, loaded %s\n", name);
    return &module_handle;
}
void
example_run_module(void* handle, int par1, int par2)
{
    printf("Yay! Running module %d: %d %d\n",
        *(int*)handle, par1, par2);
}

/* example.i */
%module example
%{
void * load_module(const char* name);
void example_run_module(void* handle, int par1, int par2);
%}  

void * load_module(const char* name);
void example_run_module(void* handle, int par1, int par2);

# SConscript
Import('env')
env.Replace(SWIGFLAGS=['-python'])
env.ParseConfig('/usr/bin/python-config --cflags --ldflags')
lib = env.SharedLibrary('_example.so', ['example.c', 'example.i'])
env.Clean(lib, 'example.pyc')

结果:

In [5]: import example

In [6]: example.load_module("hayhay")
Hoory, loaded hayhay
Out[6]: <Swig Object of type 'void *' at 0x7f18cca05180>

In [7]: import example

In [8]: x=example.load_module("hayhay")
Hoory, loaded hayhay

In [9]: example.example_run_module(x, 3, 4)
Yay! Running module 12: 3 4