I'm wrapping a third-party provided Windows DLL with SWIG for use in Python. I have been able to successfully compile my SWIG module and import it into Python, but I'm running into issues with one function (from the .h
header file):
_APPFN ServerID _CALLCONV OpenServer(HINSTANCE hAppInst, HWND hWnd);
I'm running into issues using this function, because I don't have types for HINSTANCE
or HWND
in Python. Per the documentation for this function, these values can be null, 0, or basically anything (currently an unused feature), so I'm trying to figure out how to use typemap
to make these integers so I can just pass in 0s. From my .i
file:
/* handle HINSTANCE */
%typemap(in) HINSTANCE {
$1 = PyInt_AsLong($input);
}
/* handle hwnds */
%typemap(in) HWND {
$1 = PyInt_AsLong($input);
}
When I try to compile my wrapper file (I'm using Visual Studio) with the above typemaps, I get errors: cannot convert from 'long' to 'HINSTANCE'
and cannot convert from 'long' to 'HWND'
.
Based on my reading, I believe that HINSTANCE
and HWND
are "structs", and so I need to do something in order to "cast" the struct to an integer, but unfortunately, this is all really above my head. I'm mostly a self-taught Python programmer, and dealing with C/C++ data typing is rather confusing.
I'm hoping that someone can look at what I'm doing, and guide me on how I need to change my typemapping.
These types are void*
s per the Microsoft documentation: https://docs.microsoft.com/en-us/windows/win32/winprog/windows-data-types
Although to be sure, cppyy (through Clang parsing the Windows headers) resolves them as pointers to opaque types (ie forward declared, but not defined):
$ python
>>> import cppyy
>>> print(cppyy.gbl.HWND)
<cppyy.TypedefPointerToClass object at 0x00000245E8839558>
>>>
so you may want to look up the typedefs if you want to know for sure.
However, regardless whether HWND and HINSTANCE are pointers to opaque classes or pointers to void
, even as you could cast them on 32b Windows, on 64b casting from long
to void*
(or " opaque*
") won't work because the long
value will have been truncated. So, use PyLong_AsVoidPtr
instead of PyInt_AsLong
in your typemap. See the Python C-API documentation: https://docs.python.org/3/c-api/long.html#c.PyLong_AsVoidPtr
If the types are of opaque classes, you will also need the explicit cast, and the final code would look like:
/* handle HINSTANCE */
%typemap(in) HINSTANCE {
$1 = (HINSTANCE)PyLong_AsVoidPtr($input);
}
/* handle hwnds */
%typemap(in) HWND {
$1 = (HWND)PyLong_AsVoidPtr($input);
}
Of course, if both HWND
and HINSTANCE
are indeed void*
as per that Microsoft documentation page, then that cast will be a no-op.
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.