简体   繁体   中英

Using swig c++ to python with no access to library source

I'm new to swig and tried scouring the documentation for an answer but I either missed it or didn't recognize the answer when I saw it.

I have a large C++ library from a third party for which I have no source code except the header. I need to access a few of the APIs from python and several of the APIs have function prototypes similar to:

int foo(int& a, int& b, int& c);

I've created a .i file that looks like:

%module myWrapper 
%{   
  #include libraryHeader.h
%}
extern int foo(int& m1, int& m2, int& bf);

This goes through swig, the g++ compiler and linker with no problems. I can import the module into python but when I call it I get the following error:

TypeError: in method 'foo', argument 1 of type 'int &'

I've declared 3 int variables like m1 = 0; m2 = 0; bf = 0 so I am passing something in. Is there a way to do this using the typemaps.i library or explicitly using typemaps? The documentation seems a bit vague on the subject.

Thanks in advance, Paul

SWIG needs hints where parameters are not simply inputs. These hints are provided by typemaps. You either need to define typemaps or use pre-defined ones (seetypemaps.i ).

Here's an example:

%module test

%{
    int foo(int& a, int& b, int& c)
    {
        int ret = a + b + c;
        a = 10;
        b = 20;
        c = 30;
        return ret;
    }
%}

%include <typemaps.i>
int foo(int& INOUT, int& INOUT, int& INOUT);

With the INOUT typemap, Python can pass integers into a function with for int* or int& , and the return value will be a tuple of the original return value and any output arguments. Compiling the SWIG result above and using in Python looks like this:

>>> import test
>>> test.foo(1,2,3)
[6, 10, 20, 30]

You can update variables with code like this:

>>> a,b,c = 1,2,3
>>> r,a,b,c = test.foo(a,b,c)
>>> r
6
>>> a,b,c
(10, 20, 30)

Note you can also %apply existing typemaps to types so if using %include "libraryHeader.h" instead of directly declaring functions you can use the following to generically apply the INOUT typemap to all int& parameters:

%apply int &INOUT { int& };
%include "libraryHeader.h"

I've answered my own question with the help of others on this thread and stubbornness. I created a .i file that looks like:

%module myWrapper

%include "typemaps.i"

%{
 #include "libraryHeader.h"
 typedef unsigned int MY_RESULT;
%}

typedef unsigned int MY_RESULT;
extern MY_RESULT MyGetVersion(int& OUTPUT, int& OUTPUT, int& OUTPUT, int& 
OUTPUT);
extern MY_RESULT MyGetDeviceDriverVersion(int deviceType, int& OUTPUT, int& 
OUTPUT, int& OUTPUT, int& OUTPUT);

It swigs, compiles and links cleanly and a very simple python test script returns the expected results. The script looks like:

#!/usr/bin/python3

import myWrapper

ret = 0    # function return value
maj = 0    # major version
min = 0    # minor version
bugFix = 0 # bug fix number
build = 0  # build

#
# Because of the typemap defined in myWrapper.i, we don't need to supply function arguments. 
# The results are returned by the function call as seen below...
#
ret, maj, min, bugFix, build = myWrapper.MyGetVersion()

#
# See what we got 
#
print('function return: '+str(ret)+' Maj: '+str(maj)+' Min: '+str(min)+' BugFix:'+str(bugFix)+' Build: '+str(build))

#
# This call returns the same information that the call above does but adds an input argument
# that specifies the Device Catagory. 0 is PCI
#
ret, maj, min, bugFix, build = myWrapper.MyGetDeviceDriverVersion(0)

print('function return: '+str(ret)+' Maj: '+str(maj)+' Min: '+str(min)+' BugFix: '+str(bugFix)+' Build: '+str(build))

The result of running this script provides the expected results:

function return: 0 Maj: 5 Min: 31 BugFix: 0 Build: 109
function return: 0 Maj: 4 Min: 26 BugFix: 4 Build: 253

Thank you all very much for the help and I hope that this answer can help someone else.

Paul

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.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM