hi,
here is my solution to retrieve a C double array as a python list. I
defined three C functions, returnList(), argList(), and argArray(), to
illustrate the usage. The first two work, but the last one doesn't.
I am not a python expert, and I haven't been using C for years. So
don't largh if you have easy ways to do it. I hope you guys can give
me some comments and help me working out the last case, so that I
don't have to modify C codes written before.
(you can send your comments to eric at josephdemarco dot com)
I compiled with mingw32 and distutils:
1. copy the codes below into four files: tst.i, tst.c, setup.py, and
test.py
2. Shell command: python setup.py build -cmingw32
3. copy the library _tst.pyd from build/ into current directory
4. run test.py to test
regards,
Eric
/*
* <tst.i>
*/
%module tst
%{
/* Put header files here (optional) */
%}
%inline%{
/* Generate a python list from a C double array */
PyObject *PyList_fromArray(double *pt, int n) {
PyObject *list = PyList_New(n);
int i;
for(i=0; i<n; i++) {
PyList_SetItem(list, i, PyFloat_FromDouble(pt[i]));
}
return list;
}
%}
%typemap(in,numinputs=0) PyObject **OutList(double temp) {
$1 = &temp;
}
%typemap(argout) PyObject **OutList {
PyObject *o, *o2, *o3;
o = *$1;
if ((!$result) || ($result == Py_None)) {
$result = o;
} else {
if (!PyTuple_Check($result)) {
PyObject *o2 = $result;
$result = PyTuple_New(1);
PyTuple_SetItem($result,0,o2);
}
o3 = PyTuple_New(1);
PyTuple_SetItem(o3,0,o);
o2 = $result;
$result = PySequence_Concat(o2,o3);
Py_DECREF(o2);
Py_DECREF(o3);
}
}
%typemap(in,numinputs=0) double **OutArray(double temp) {
$1 = &temp;
}
%typemap(argout) double **OutArray {
PyObject *o, *o2, *o3;
o = PyList_fromArray($1, 3);
if ((!$result) || ($result == Py_None)) {
$result = o;
} else {
if (!PyTuple_Check($result)) {
PyObject *o2 = $result;
$result = PyTuple_New(1);
PyTuple_SetItem($result,0,o2);
}
o3 = PyTuple_New(1);
PyTuple_SetItem(o3,0,o);
o2 = $result;
$result = PySequence_Concat(o2,o3);
Py_DECREF(o2);
Py_DECREF(o3);
}
}
extern PyObject *returnList(void);
extern void argList(PyObject **OutList);
extern void argArray(double **OutArray);
/*
* <tst.c>
*/
#include <Python.h>
/* An example to return a C array as a python list */
PyObject *returnList(void) {
double a[3];
int i;
for(i=0; i<3; i++ ) {
a[i] = (double) i ;
}
return PyList_fromArray(a, 3);
}
/* An example to assign a C array to an argument pointer */
void argList(PyObject **list) {
double a[3];
int i;
for(i=0; i<3; i++ ) {
a[i] = (double) i * 2;
}
*list = PyList_fromArray(a, 3);
}
/* An example to assign a C array to an argument pointer */
void argArray(double **list) {
double a[3];
int i;
for(i=0; i<3; i++ ) {
a[i] = (double) i * 2;
}
*list = a;
}
# <setup.py>
#!c:/python23/python
import distutils
from distutils.core import setup, Extension
setup(name = "An example showing how to retreive a C array as a python
list",
version = "2.2",
ext_modules = [Extension("_tst", ["tst.i","tst.c"])])
# <test.py>
#!c:/python23/python
import _tst
print _tst.returnList()
print _tst.argList()
print _tst.argArray()
_______________________________________________
Swig maillist - Swig@xxxxxxxxxxxxxxx
http://mailman.cs.uchicago.edu/mailman/listinfo/swig
Thread at a glance:
Previous Message by Date:
click to view message preview
Re: function like macros and abstract classes
On Sat, 24 Jul 2004, Tamer Fahmy wrote:
> if i remove the parantheses from FOO1 everything works again.
> e.g.:
> #define FOO1 \
> private: \
> void bar1()
>
> #define FOO2(param1) \
> FOO1; \
> public: \
> void bar2(param1)
>
> i had no such problem with swig version 1.3.19. so i wonder if this is
> correct behaviour and the header files on my side should get fixed or
> does this qualify as a bug in swig 1.3.21 upwards (also tested it
I think you've encountered the bug described at
http://sourceforge.net/tracker/index.php?func=detail&aid=882225&group_id=1645&atid=101645.
You should be able to see what's happening by running swig -E. If
changing the C++ to use parentheses-less macros is not an option, you
might be able to work around this by redefining some macros in your
interface file. In this particular case it's not clear to me why the FOO1
macro exists, and you might be able to just redefine FOO2 for swig so that
it doesn't use FOO1.
Josh
--
Joshua L. Cherry, Ph.D.
NCBI/NLM/NIH (Contractor)
jcherry@xxxxxxxxxxxxxxxx
_______________________________________________
Swig maillist - Swig@xxxxxxxxxxxxxxx
http://mailman.cs.uchicago.edu/mailman/listinfo/swig
Next Message by Date:
click to view message preview
Re: function like macros and abstract classes
hi Josh!
On Sa, 2004-07-24 at 14:52, Josh Cherry wrote:
> I think you've encountered the bug described at
> http://sourceforge.net/tracker/index.php?func=detail&aid=882225&group_id=1645&atid=101645.
it seems to be exactly the issue i encountered.
> You should be able to see what's happening by running swig -E. If
> changing the C++ to use parentheses-less macros is not an option, you
> might be able to work around this by redefining some macros in your
> interface file. In this particular case it's not clear to me why the FOO1
> macro exists, and you might be able to just redefine FOO2 for swig so that
> it doesn't use FOO1.
i guess it has been done for the sake of consistency and not for
optimization and the offending ones are anyways private to the context
of usage in the header files. so i'll give it a try and ask them to
change it if it isn't going to be fixed any time soon in swig. in any
case i already fixed this by providing my own patched header files for
these cases.
thx for pointing out the issue tracker link and the -E option!
cheers,
tamer.
--
robot farm: machines good, people bad!
signature.asc
Description: This is a digitally signed message part
Previous Message by Thread:
click to view message preview
How to retrieve a dynamically allocated array in a c function as a python list?
This might be a clearer question: how to retrieve a dynamically
allocated double array in a c function as a python list?
I made an attempt, but got an empty list. Could anyone tell me what's
wrong?
%typemap(in,numinputs=0) double *Output (double temp) {
$1 = &temp;
}
%typemap(argout) double *Output {
PyObject *o, *o2, *o3;
int i;
o = PyList_New(4); // o stores the value assigned to this variable,
transformation can be done here
for(i = 0; i < 4; i++) {
PyList_SetItem(o, i, PyFloat_FromDouble($1[i]));
}
if ((!$result) || ($result == Py_None)) {
$result = o;
} else {
if (!PyTuple_Check($result)) {
PyObject *o2 = $result;
$result = PyTuple_New(1);
PyTuple_SetItem($result,0,o2);
}
o3 = PyTuple_New(1);
PyTuple_SetItem(o3,0,o);
o2 = $result;
$result = PySequence_Concat(o2,o3);
Py_DECREF(o2);
Py_DECREF(o3);
}
}
_______________________________________________
Swig maillist - Swig@xxxxxxxxxxxxxxx
http://mailman.cs.uchicago.edu/mailman/listinfo/swig
Next Message by Thread:
click to view message preview
RE: Making exceptions native in Java binding
>-----Original Message-----
>From: swig-admin@xxxxxxxxxxxxxxx [mailto:swig-admin@xxxxxxxxxxxxxxx]On
>Behalf Of Russell Keith-Magee
>Sent: 22 July 2004 01:40
>To: swig@xxxxxxxxxxxxxxx
>Subject: [Swig] Making exceptions native in Java binding
>
>
>
>Hi all,
>
>I have been investigating SWIG to see if I can use it to build
>Java bindings
>for a C++ library I am currently developing. So far, SWIG has
>been really
>impressive. Kudos to all concerned.
>
>The only problem I have had has been with exceptions. I have a
>C++ class,
>with a method that throws an exception. The exception is
>another C++ class.
>Using the default SWIG exception handlers, I have generated
>Java bindings
>for the two classes.
>
>When wrapped in Java bindings, I can call the C++ method from
>within Java,
>which causes the C++ method to throw an exception, which in
>turn causes the
>Java method to throw an exception. However, the exception that
>is thrown in
>Java is a java.lang.RuntimeException, with a message that
>includes the name
>of the C++ exception class.
>
>This is all well and good (and I can see why this is the
>default behavior),
>but not particularly practical for Java developers if the C++
>method throws
>a lot of different exceptions.
>
>I have been trying to work out if there is a way to make the
>Java bindings a
>little more java-like - i.e., I would like to be able to "catch
>(TestException t)" on the Java side, rather than just catching
>RuntimeException and searching for TestException in the message string.
>
>There are really three parts to the problem:
>- modifying the exception handler for the C++ binding to raise
>the right
>exception
>- modifying the Java binding for the Exception class to extend
>java.lang.exception
>- modifying the Java binding for the method to include a
>"raises" clause.
>
>I can see how I might be able to do the first of these using
>an %exception
>block; I can't work out how to do the remaining two (short of manually
>modifying the generated code - and there has to be a better
>way than that).
>
>I've included a cut down example that shows the sort of
>behavior I would
>like to have. There are three source files (a cpp, h, and java
>file); the .h
>file doubles as a SWIG interface. The last file (java) has a
>block commented
>out with the behavior I would like.
>
>Many thanks,
>Russ Magee
>
>
>--------------------------------- example.h (double as interface file)
>#ifndef __EXAMPLE_H
>#define __EXAMPLE_H
>
>#ifdef SWIG
>%module example
>%{
>#include "example.h"
>%}
>
>#endif
>
>#include <iostream>
>
>class TestException : std::exception
>{
> std::string _message;
>public:
> TestException(std::string message);
>};
>
>class Caller
>{
>public:
> Caller();
> ~Caller();
> void operation() throw(TestException);
>};
>
>#endif
>
>--------------------------------- example.cpp
>#include "example.h"
>
>TestException::TestException(std::string message)
>{
> _message = message;
>}
>
>Caller::Caller()
>{
>}
>
>Caller::~Caller()
>{
>}
>
>void Caller::operation() throw(TestException)
>{
> std::cout << "Do some stuff" << std::endl;
> throw TestException("Bad stuff");
>}
>
>--------------------------------- main.java
>public class main
>{
> static {
> try {
> System.loadLibrary("example");
> } catch (UnsatisfiedLinkError e) {
> System.err.println("Native code library failed to load: " + e);
> System.exit(1);
> }
> }
>
> public static void main(String[] args)
> {
> Caller caller = new Caller();
>
> System.out.println();
> System.out.println("Call a C++ operation that throws an
>exception");
> System.out.println("------------------------------------");
>
> try
> {
> caller.operation();
> }
>//******************************************************
>// THIS IS THE BIT THAT DOESN'T REALLY WORK AS EXPECTED
>// You can't catch TestException; only runtime exception
>//******************************************************
>// catch (TestException e)
>// {
>// System.out.println("Test Exception thrown: " + e);
>// }
>//*****************************************************
> catch (java.lang.RuntimeException e)
> {
> System.out.println("Runtime exception thrown: " + e);
> }
> }
>}
>---------------------------------
>
The documentation on how to deal with exceptions with Java was added just
recently. See the updated Java.html file in the CVS repository. Since
SWIG-1.3.21 the %javaexception directive is new, so you'll have to use the CVS
version for this. The rest can be achieved with 1.3.21. If you can't use the
CVS version there are hacks using typemaps which are in mailing list archives
if you can find them.
CVS version of Java.html, if you can't check it out from the repository:
http://cvs.sourceforge.net/viewcvs.py/*checkout*/swig/SWIG/Doc/Manual/Java.html?content-type=text%2Fplain
For your TestException to use java.lang.Exception, you may need to use
class std::exception;
%rename(java.lang.Exception) std::exception;
instead of something like
%typemap(javabase) TestException "java.lang.Exception";
Do you mean a throws clause instead of raises clause? If so that is all covered
in the docs.
William
--
Visit our website at http://www.ubs.com
This message contains confidential information and is intended only
for the individual named. If you are not the named addressee you
should not disseminate, distribute or copy this e-mail. Please
notify the sender immediately by e-mail if you have received this
e-mail by mistake and delete this e-mail from your system.
E-mail transmission cannot be guaranteed to be secure or error-free
as information could be intercepted, corrupted, lost, destroyed,
arrive late or incomplete, or contain viruses. The sender therefore
does not accept liability for any errors or omissions in the contents
of this message which arise as a result of e-mail transmission. If
verification is required please request a hard-copy version. This
message is provided for informational purposes and should not be
construed as a solicitation or offer to buy or sell any securities or
related financial instruments.
_______________________________________________
Swig maillist - Swig@xxxxxxxxxxxxxxx
http://mailman.cs.uchicago.edu/mailman/listinfo/swig