-2

I basically want to do exactly this:

swig: how to pass void* into generic function

I seem to be able to get a value that Python can hold, but when I pass it back in, it is deemed null and causes a fail. So I'm thinking I need some kind of PyObject conversion. I don't know why void pointers should be so hard to handle.

(I'm actually working with HMODULE, but I think if I can get void pointers to work, I can get them to work as well.

Basically, I just want to:

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

How do I define the input and output typemaps such that these two calls can be supported?

I am trying to work with HMODULE (defined in Windows.h , eventually as a void pointer)

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

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

I have figured out my actual problem.

My routines when wrapped would be:

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

The problem is that the returned name is a char string (char *) but the LoadLibrary() MSDN routine needs a LPCWSTR. I can readily convert the string within the routine, but that breaks it for other use, so I'd really like to convert the string within an input wrapper.

I think the solution is a typemap of some sort.

I am trying this:

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

This is failing. It seems to thing the input is a python string object, so I somehow have to get it to convert it to a char * before applying the next conversion.

How do I get this input string converted?

ANSWER:

OK, I found a (the?) fix. The trick is to use 'check' which adds code after the default conversion:

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

1 Answers1

2

Swig supports that usage directly, with no typemaps required.

One way to get your code snippet to work is as follows:

/* 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')

Result:

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
Robᵩ
  • 163,533
  • 20
  • 239
  • 308
  • OK, trying this out -- I hope it will be this easy. – Jiminion May 18 '16 at 19:28
  • OK, I think I see the current problem. Since my actual pointer is an HMODULE, my load_module needs to be defined to return that in both instances. It stores it OK as a PyObject in Python, but when it comes time to send it back, it is not read, or read as null. – Jiminion May 18 '16 at 19:43
  • Type returned is – Jiminion May 18 '16 at 19:45
  • 1
    Can you provide a short, complete example, including the actual and expected output? Please post that example into your question. See [mcve] for more info. – Robᵩ May 18 '16 at 20:00
  • Shoot. It seems to be the string name input. LoadLibrary isn't working, which is why the null is there. So I gotta check that.... – Jiminion May 18 '16 at 20:40
  • @jim Once someone has taken the time to answer your question please don't edit it into a completely different one that makes their efforts wasted. – Flexo May 20 '16 at 10:16
  • It ended up being a completely different problem. I didn't remove the answer. – Jiminion May 20 '16 at 13:21
  • I thought the real problem was worth noting -- I'd have liked to have seen it 24 hours ago! I meant no disrespect to Robphi. – Jiminion May 20 '16 at 13:28