SWIG/Python: 将指针传递给函数
SWIG/Python: Passing pointer into function
我基本上就是想这样做:
swig: how to pass void* into generic function
我似乎能够得到一个 Python 可以容纳的值,但是当我将它传回时,它被视为 null 并导致失败。所以我想我需要某种 PyObject 转换。我不知道为什么 void 指针这么难处理。
(我实际上正在使用 HMODULE,但我认为如果我能让 void 指针工作,我也能让它们工作。
基本上,我只想:
>>hmod = example.load_module("fooModName")
>>example.run_module(hmod, par1, par2)
如何定义输入和输出类型映射以支持这两个调用?
我正在尝试使用 HMODULE(在 Windows.h 中定义,最终作为空指针)
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 *),但 LoadLibrary() MSDN 例程需要一个 LPCWSTR。我可以很容易地在例程中转换字符串,但这会破坏它以供其他用途,所以我真的很想在输入包装器中转换字符串。
我认为解决方案是某种类型映射。
我正在尝试这个:
%typemap(in) char* inpathDLL {
static wchar_t LpathDLL[2048];
MultiByteToWideChar(CP_ACP, 0, $input, -1, LpathDLL, 2048);
= LpathDLL;
}
这是失败的。似乎输入是一个 python 字符串对象,所以在应用下一个转换之前,我必须以某种方式将它转换为 char *。
如何转换此输入字符串?
答案:
好的,我找到了(那个?)修复程序。诀窍是使用 'check' 在默认转换后添加代码:
%typemap(check)char* inpathDLL {
if ( != NULL) {
static wchar_t LpathDLL[2048];
MultiByteToWideChar(CP_ACP, 0, , -1, LpathDLL, 2048);
= (char *)LpathDLL;
}
}
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
我基本上就是想这样做:
swig: how to pass void* into generic function
我似乎能够得到一个 Python 可以容纳的值,但是当我将它传回时,它被视为 null 并导致失败。所以我想我需要某种 PyObject 转换。我不知道为什么 void 指针这么难处理。
(我实际上正在使用 HMODULE,但我认为如果我能让 void 指针工作,我也能让它们工作。
基本上,我只想:
>>hmod = example.load_module("fooModName")
>>example.run_module(hmod, par1, par2)
如何定义输入和输出类型映射以支持这两个调用?
我正在尝试使用 HMODULE(在 Windows.h 中定义,最终作为空指针)
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 *),但 LoadLibrary() MSDN 例程需要一个 LPCWSTR。我可以很容易地在例程中转换字符串,但这会破坏它以供其他用途,所以我真的很想在输入包装器中转换字符串。
我认为解决方案是某种类型映射。
我正在尝试这个:
%typemap(in) char* inpathDLL {
static wchar_t LpathDLL[2048];
MultiByteToWideChar(CP_ACP, 0, $input, -1, LpathDLL, 2048);
= LpathDLL;
}
这是失败的。似乎输入是一个 python 字符串对象,所以在应用下一个转换之前,我必须以某种方式将它转换为 char *。
如何转换此输入字符串?
答案:
好的,我找到了(那个?)修复程序。诀窍是使用 'check' 在默认转换后添加代码:
%typemap(check)char* inpathDLL {
if ( != NULL) {
static wchar_t LpathDLL[2048];
MultiByteToWideChar(CP_ACP, 0, , -1, LpathDLL, 2048);
= (char *)LpathDLL;
}
}
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