■ 파이썬_01
Nabble.addCssRule(document.styleSheets[0],'.nabble a:link','color:'+document.linkColor); Nabble.addCssRule(document.styleSheets[0],'.nabble a:visited','color:'+document.vlinkColor);
if (!Nabble.isEmbedded) { document.write('Nabble | Old Nabble1'); } else if (false) { document.write('Back to the forum'); } Nabble | Old Nabble1 | Software ≫ SourceForge ≫ SWIG ≫ swig-user Login : Register
Nabble.userHeader(3366);
Swig Python/Autocad binding
View: Threaded Chronologically All Messages Nabble.selectOption(Nabble.get("nabble.viewSelect"),Nabble.tview); New views 9 Messages ? Rating Filter: 0 1 2 3 4 5 Alert me if( Nabble.user == 799921 || Nabble.user == 77858) { document.writeln('Move thread'); }
Swig Python/Autocad binding document.write(Nabble.ratingStars(3));
by document.write(' Mick Duprez document.write(''); document.write(Nabble.formatDateLong(new Date(1219651075018))); Aug 25, 2008; 04:57pm :: Rate this Message: - Use ratings to moderate (?)
document.writeln('Reply | '); Reply | Reply to Author if( Nabble.user == 799921 ) { document.writeln('| Edit'); document.writeln('| Delete'); } else if( Nabble.user == 77858 ) { document.writeln('| Delete'); } document.writeln('| Print'); | Print | View Threaded | Show Only this Message
Hi All,
I've been trying to wrap the AutoCAD ARX api (ARX is the app's C++ SDK) with some success but am stumped at the moment with what may be a simple problem.
The wrapper seems to work with some methods but not others.
For instance, I can call a wrapped global function no problem, this was the first test to see if the wrapper was going to work. Now that I've wrapped some C++ classes I've hit a snag, I seem to be able to call a simple method from a class but when I try to debug other methods the breakpoints are not getting hit and I receive an error and the method in Python fails.
As I have no debugging from Python i can print what the pyobject is to the autocad command line using str(object) and I am indeed getting a pointer to a proxy object, it's functions are just not getting called. The functions are overloaded and swig has produced the code to decide which one to call and I have set bp's at each one and none get hit.
Any help greatly appreciated, if you need the solution or for me to post some code (the .i file is quite large but I can post bit's you might need to look at), just let me know.
Thanks,
Mick.
Some set up details -
winXP SP2
VS2005 std SP1
Python 2.5.2
SWIG 1.3.36
AutoCAD 2008 SDK
google_protectAndRun("render_ads.js::google_render_ad", google_handleError, google_render_ad); if (Nabble.searchterms != null && Nabble.searchterms.length > 0) { Nabble.hilt(Nabble.searchterms, Nabble.get("nabble.msgtxt19139435")); }
Re: Swig Python/Autocad binding document.write(Nabble.ratingStars(3));
by document.write(' Mick Duprez document.write(''); document.write(Nabble.formatDateLong(new Date(1219652839081))); Aug 25, 2008; 05:27pm :: Rate this Message: - Use ratings to moderate (?)
document.writeln('Reply | '); Reply | Reply to Author if( Nabble.user == 799921 ) { document.writeln('| Edit'); document.writeln('| Delete'); } else if( Nabble.user == 77858 ) { document.writeln('| Delete'); } document.writeln('| Print'); | Print | View Threaded | Show Only this Message
Just thought I'd add how the project is set up.
In autocad I've made an arx(dll) plug in that embeds the Python interpreter. From here I have some functions that register python script callbacks in a PyDict which are called from autocad commands.
The callbacks are python methods with no args and they all go through the same C++ static function to call the method. My autocad code catches the command from the user, searches the dict for the command string (key) whose value is the python script callback and it's pushed through the C++ function to execute using the C Python api.
I import my wrapped module/s into the script with the callback and interact with the main app as required then return back to the main app.
hope that gives some further insight,
cheers.
if (Nabble.searchterms != null && Nabble.searchterms.length > 0) { Nabble.hilt(Nabble.searchterms, Nabble.get("nabble.msgtxt19139804")); }
Re: Swig Python/Autocad binding document.write(Nabble.ratingStars(3));
by document.write(' Mick Duprez document.write(''); document.write(Nabble.formatDateLong(new Date(1219922939810))); Aug 28, 2008; 08:28pm :: Rate this Message: - Use ratings to moderate (?)
document.writeln('Reply | '); Reply | Reply to Author if( Nabble.user == 799921 ) { document.writeln('| Edit'); document.writeln('| Delete'); } else if( Nabble.user == 77858 ) { document.writeln('| Delete'); } document.writeln('| Print'); | Print | View Threaded | Show Only this Message
No takers yet :)
Ok, another question that may even solve a big part of the problem.
I've read here and other places that when embedding an interpreter I should also compile the swig interface with it. Is this the correct way?
I've tried both with no real difference, the only thing is I can't call SWIG_init() (which I think is key here) as my wrapper file doesn't have a header file, should I just create one and add it to the interface file so I can 'include' it in my dll entry point file?
I have done extensive searching here and elswhere but a lot of posts glaze over some details that some long time users take for granted (or I still don't understand), so, if someone can give me a basic setup/direction of how I should be doing this that would be greatly appreciated.
My goal is to create a dll that's imported into the main application and embeds a Python interpreter. Using the swig wrapped api I'd like to write scripts callable form the main application through this dll, this part I have worked out fine, it's my interface/glue code with the swig wrapped api that's not working so far.
Thanks,
cheers,
Mick.
if (Nabble.searchterms != null && Nabble.searchterms.length > 0) { Nabble.hilt(Nabble.searchterms, Nabble.get("nabble.msgtxt19198652")); }
Re: Swig Python/Autocad binding document.write(Nabble.ratingStars(3));
by document.write(' mark gossage document.write(''); document.write(Nabble.formatDateLong(new Date(1220237901000))); Sep 01, 2008; 11:58am :: Rate this Message: - Use ratings to moderate (?)
document.writeln('Reply | '); Reply | Reply to Author if( Nabble.user == 220699 ) { document.writeln('| Delete'); } else if( Nabble.user == 77858 ) { document.writeln('| Delete'); } document.writeln('| Print'); | Print | View Threaded | Show Only this Message
>
> No takers yet :)
>
> Ok, another question that may even solve a big part of the
> problem.
>
> I've read here and other places that when embedding an
> interpreter I should
> also compile the swig interface with it. Is this the
> correct way?
>
> I've tried both with no real difference, the only thing
> is I can't call
> SWIG_init() (which I think is key here) as my wrapper file
> doesn't have a
> header file, should I just create one and add it to the
> interface file so I
> can 'include' it in my dll entry point file?
>
> I have done extensive searching here and elswhere but a lot
> of posts glaze
> over some details that some long time users take for
> granted (or I still
> don't understand), so, if someone can give me a basic
> setup/direction of how
> I should be doing this that would be greatly appreciated.
>
> My goal is to create a dll that's imported into the
> main application and
> embeds a Python interpreter. Using the swig wrapped api
> I'd like to write
> scripts callable form the main application through this
> dll, this part I
> have worked out fine, it's my interface/glue code with
> the swig wrapped api
> that's not working so far.
>
> Thanks,
> cheers,
> Mick.
>
...[show rest of quote]
Hello Mick,
Where to start....
As far as I read from you post, what you a looking to do is to embed a python interpreter into your C/C++ Autocad application, and then have it call a bunch of the Autocad functions.
This is two seperate matters: 1. embedding the python interpreter, 2. calling Autocad functions.
SWIG will easily perform 2 for you, but on part 1, you have to DIY.
Dealing with part 2 first: what you do is create a .i file with all your functions to wrapper in that, and feed to SWIG. It will then create the bindings for you. Job done.
For part 1, this is harder. The python documentation on embedding is not very good. I you believe: http://davidf.sjsoft.com/mirrors/mcmillan-inc/embed.html I guess python is not meant for this task.
However http://www.linuxjournal.com/article/8497 does give a very simple example of embedding which you could work with.
To add the SWIG bindings to this is just one more line of code.
Expanding one of the examples from the previous article:
void exec_pycode(const char* code)
{
Py_Initialize();
Example_init(); // call SWIG module
PyRun_SimpleString(code);
Py_Finalize();
}
But the whole business of embedding Python is not so easy to do. I would start by just adding a simple embed (as this) and try to call some python from Autocad, then try adding one autocad function to see if you can do it.
Hope this helps,
Mark
-------------------------------------------------------------------------
This SF.Net email is sponsored by the Moblin Your Move Developer's challenge
Build the coolest Linux based applications with Moblin SDK & win great prizes
Grand prize is a trip for two to an Open Source event anywhere in the world
http://moblin-contest.org/redirect.php?banner_id=100&url=/
_______________________________________________
Swig-user mailing list
Swig-user@...
https://lists.sourceforge.net/lists/listinfo/swig-user
if (Nabble.searchterms != null && Nabble.searchterms.length > 0) { Nabble.hilt(Nabble.searchterms, Nabble.get("nabble.msgtxt19248314")); }
Re: Swig Python/Autocad binding document.write(Nabble.ratingStars(3));
by document.write(' Mick Duprez document.write(''); document.write(Nabble.formatDateLong(new Date(1220243199877))); Sep 01, 2008; 01:26pm :: Rate this Message: - Use ratings to moderate (?)
document.writeln('Reply | '); Reply | Reply to Author if( Nabble.user == 799921 ) { document.writeln('| Edit'); document.writeln('| Delete'); } else if( Nabble.user == 77858 ) { document.writeln('| Delete'); } document.writeln('| Print'); | Print | View Threaded | Show Only this Message
Thanks Mark,
I have the Python interpreter embeded ok and I have manually wrapped some code with little problem, I can use the COM api from Python scripts at the moment and I have the callbacks all organised.
I have successfully compiled a SWIG module and I can get a global method to work, but if I try to call a class method I get an error and my callback fails to finish the task.
I have set break points in the SWIG code for debugging but they are not being hit, the global method gets hit ok, just not the class methods.
There is nothing real special about the C++ classes I'm wrapping and SWIG is generating what looks like the class interface code ok, maybe I need an extra swig preprocessing helper or something(?).
I'll do some more study tonight and see if I can spot anything else I'm missing.
Cheers,
Mick.
PS. As I only have limited debugging on the python side, I am using a print statement to see if I have created an object in Python, it's seems as though I am but I don't think I'm getting one on the C++ side, and that's where the problem lies I think.
if (Nabble.searchterms != null && Nabble.searchterms.length > 0) { Nabble.hilt(Nabble.searchterms, Nabble.get("nabble.msgtxt19248754")); }
Re: Swig Python/Autocad binding document.write(Nabble.ratingStars(3));
by document.write(' Mick Duprez document.write(''); document.write(Nabble.formatDateLong(new Date(1220869144162))); Sep 08, 2008; 07:19pm :: Rate this Message: - Use ratings to moderate (?)
document.writeln('Reply | '); Reply | Reply to Author if( Nabble.user == 799921 ) { document.writeln('| Edit'); document.writeln('| Delete'); } else if( Nabble.user == 77858 ) { document.writeln('| Delete'); } document.writeln('| Print'); | Print | View Threaded | Show Only this Message
So far I've tried just about everything, features, inline helpers and read the doc's more than a few times, I just can't get something that seems/claims to be so simple to do anything useful. The only thing that seems to work is if I wrap what I need into %inline helper functions.
Here is part of one of the more complicated classes, is there something obvious I'm missing here?
The only time you create a new object is if you're creating a new file, hence the only ctor.
Normally you wold use a global function to get the 'active' db object then use its methods add/remove/modify obects, when I call getBlockTable below it fails, if I try to unload the dll hosting the interpreter it crashes the main app.
class AcDbDatabase: public AcRxObject, public AcHeapOperators
//
// A class whose instances represent an entire DWG file,
// aka database itself.
//
{
public:
virtual AcRxClass* isA() const;
static AcRxClass* desc();
static AcDbDatabase* cast(const AcRxObject* inPtr)
{ return ((inPtr == NULL) || !inPtr->isKindOf(AcDbDatabase::desc()))
? NULL : (AcDbDatabase*)inPtr; };
// constructor & destructor
AcDbDatabase(bool buildDefaultDrawing = true,
bool noDocument = false);
virtual ~AcDbDatabase();
// a typical call to get another object I've wrapped also:
Acad::ErrorStatus getBlockTable (AcDbSymbolTable*& pTable,
AcDb::OpenMode mode);
.... and so on.
Here's some python code, please excuse it :) -
def addline():
try:
sp = pyacdb.AcGePoint3d(30.0,45.0,0.0)
ep = pyacdb.AcGePoint3d(120.0,120.0,0.0)
line = pyacdb.AcDbLine(sp,ep)
pyacdb.acutPrintf ('\nIn addline6.1 ...\n') #this works fine, global function
pDb = pyacdb.acdbWorkingDatabase()
pyacdb.acutPrintf ('\nIn addline7...\n') #I'm getting to here....
pDb.getBlockTable(pBt, AcDb.kForRead)
pyacdb.acutPrintf ('\nIn addline7.1..\n') #not making it here though!!!
pBt.getAt('*Model_Space',pBtr,AcDb.kForWrite)
pyacdb.acutPrintf ('\nIn addline7.2..\n')
pBt.close
pyacdb.acutPrintf ('\nIn addline8...\n')
id = pyacdb.AcDbObjectId()
pyacdb.acutPrintf ('\nIn addline9...\n')
pBtr.appendAcDbEntity(id,line)
pyacdb.acutPrintf ('\nIn addline10...\n')
pBtr.close
pyacdb.acutPrintf ('\nwOOOOt!!...\n')
except:
msg = "Unexpected error:" + sys.exc_info()[0]
pyacdb.acutPrintf (msg)
raise
and here's the main part of the calling method in the interpreter hosting dll -
// grab the callback from the PyDict and call it:
PyObject *arglist;
PyObject *result, *func;
arglist = Py_BuildValue("()");
func = PyDict_GetItemString(pCmdDict,pyStr);
if (PyCallable_Check(func))
{
result = PyEval_CallObject(func, arglist);
}
Py_DECREF(arglist);
if (result == NULL)
{
acutPrintf(_T("PyArxError: Failed to call Python callback.\n"));
return;
}
Py_DECREF(result);
if(pyStr)
{
free(pyStr);
}
What I do here is, when I load the interpreter I call into an 'initialiser' .py file which calls an embedded method using straight python extension code to load method callbacks into a dict object, the application calls a method callback in the dict by it's string key as a command using the code above.
This works pretty well so far (all though it needs more error handling to stop trashing the host's memory), it seems as if I'm either loosing my pointer to the database object or it's not 'really' creating one??
I feel I'm just one step away but my eyes have all but glazed over from all this study and testing to no avail. Swig is wrapping as much or as little as I need with little trouble, it's just not working as I would have hoped.
Thank you,
Mick.
if (Nabble.searchterms != null && Nabble.searchterms.length > 0) { Nabble.hilt(Nabble.searchterms, Nabble.get("nabble.msgtxt19369352")); }
Re: Swig Python/Autocad binding document.write(Nabble.ratingStars(3));
by document.write(' Steven Hirsch document.write(''); document.write(Nabble.formatDateLong(new Date(1220874578000))); Sep 08, 2008; 08:49pm :: Rate this Message: - Use ratings to moderate (?)
document.writeln('Reply | '); Reply | Reply to Author if( Nabble.user == 804348 ) { document.writeln('| Delete'); } else if( Nabble.user == 77858 ) { document.writeln('| Delete'); } document.writeln('| Print'); | Print | View Threaded | Show Only this Message
On Mon, 8 Sep 2008, Mick Duprez wrote:
> So far I've tried just about everything, features, inline helpers and read
> the doc's more than a few times, I just can't get something that
> seems/claims to be so simple to do anything useful. The only thing that
> seems to work is if I wrap what I need into %inline helper functions.
>
> Here is part of one of the more complicated classes, is there something
> obvious I'm missing here?
> The only time you create a new object is if you're creating a new file,
> hence the only ctor.
> Normally you wold use a global function to get the 'active' db object then
> use its methods add/remove/modify obects, when I call getBlockTable below it
> fails, if I try to unload the dll hosting the interpreter it crashes the
> main app.
...[show rest of quote]
I must be missing something in your sample code. Where's the constructor
for the database object? You are showing code that tries to use the
object, but are not detailing where it comes from and how?
Steve
-
-------------------------------------------------------------------------
This SF.Net email is sponsored by the Moblin Your Move Developer's challenge
Build the coolest Linux based applications with Moblin SDK & win great prizes
Grand prize is a trip for two to an Open Source event anywhere in the world
http://moblin-contest.org/redirect.php?banner_id=100&url=/
_______________________________________________
Swig-user mailing list
Swig-user@...
https://lists.sourceforge.net/lists/listinfo/swig-user
if (Nabble.searchterms != null && Nabble.searchterms.length > 0) { Nabble.hilt(Nabble.searchterms, Nabble.get("nabble.msgtxt19370442")); }
Re: Swig Python/Autocad binding document.write(Nabble.ratingStars(3));
by document.write(' Mick Duprez document.write(''); document.write(Nabble.formatDateLong(new Date(1220905863001))); Sep 09, 2008; 05:31am :: Rate this Message: - Use ratings to moderate (?)
document.writeln('Reply | '); Reply | Reply to Author if( Nabble.user == 799921 ) { document.writeln('| Edit'); document.writeln('| Delete'); } else if( Nabble.user == 77858 ) { document.writeln('| Delete'); } document.writeln('| Print'); | Print | View Threaded | Show Only this Message
Steven Hirsch wrote:
On Mon, 8 Sep 2008, Mick Duprez wrote:
> So far I've tried just about everything, features, inline helpers and read
> the doc's more than a few times, I just can't get something that
> seems/claims to be so simple to do anything useful. The only thing that
> seems to work is if I wrap what I need into %inline helper functions.
>
> Here is part of one of the more complicated classes, is there something
> obvious I'm missing here?
> The only time you create a new object is if you're creating a new file,
> hence the only ctor.
> Normally you wold use a global function to get the 'active' db object then
> use its methods add/remove/modify obects, when I call getBlockTable below it
> fails, if I try to unload the dll hosting the interpreter it crashes the
> main app.
I must be missing something in your sample code. Where's the constructor
for the database object? You are showing code that tries to use the
object, but are not detailing where it comes from and how?
Steve
...[show rest of quote]
Hi Steve,
here's the constructor/destructor -
// constructor & destructor
AcDbDatabase(bool buildDefaultDrawing = true,
bool noDocument = false);
virtual ~AcDbDatabase();
At most times you wouldn't need to create a db object as it already exists but you can get a pointer to it using some global functions, the acdbWorkingDatabase() method in the python script is a wrapped helper that 'is' getting called. the eg.
pDb = pyacdb.acdbWorkingDatabase() # get a pointer to a pDb (AcDbDatabase) object
These appear to be working when stepping through code in the debugger but when I call a method on the db object it isn't entering the swig wrapper code and my break points are not being hit.
I wouldn't think you would need an empty/default ctor if the db already existed and I'm not sure how the hosting app would respond creating an object without the default param's?
I did read somewhere though about swig making a new object that then uses a copyctor to put the pointer in but I don't think the host app would like that, does swig do this for 'every' class object being wrapped?
thanks.
Mick.
if (Nabble.searchterms != null && Nabble.searchterms.length > 0) { Nabble.hilt(Nabble.searchterms, Nabble.get("nabble.msgtxt19380559")); }
Re: Swig Python/Autocad binding document.write(Nabble.ratingStars(3));
by document.write(' Mick Duprez document.write(''); document.write(Nabble.formatDateLong(new Date(1221045819290))); Sep 10, 2008; 08:23pm :: Rate this Message: - Use ratings to moderate (?)
document.writeln('Reply | '); Reply | Reply to Author if( Nabble.user == 799921 ) { document.writeln('| Edit'); document.writeln('| Delete'); } else if( Nabble.user == 77858 ) { document.writeln('| Delete'); } document.writeln('| Print'); | Print | View Threaded | Show Only this Message
Ok, a bit more testing revealed I can call a method if I wrap the c++ code into C helper functions, the C++ class functions are still not working.
Here's my code in the interface file for the helper functions, these work fine, the C++ code is as per the earlier post (or a typical class).
.....................
%inline {
AcDbDatabase* acdb_getCurrentDb()
{
AcDbDatabase* pDb;
pDb = acdbHostApplicationServices()->workingDatabase();// api func that returns active db*
return pDb;
}
}
%inline {
const ACHAR* acdb_getFileName(AcDbDatabase* pDb)
{
const ACHAR* filename;
pDb->getFilename(filename);// get the db*'s filename
return filename;
}
}
int acutPrintf(const ACHAR* format, ...); // function to print string output to autocad command line/prompt
......................
these are the 2 python script functions I call that grab the current database object pointer and then get it's filename member variable.
.........................
def print_msg1(): #called with 'PY1' command
#using swig wrapper, no helper:
pDb1 = pyacdb.acdbWorkingDatabase()
dbstring = str(pDb1) + '\n'
pyacdb.acutPrintf(dbstring)
filename = ' '
pDb1.getFilename(filename) #call a C++ member function, fails here!!!!
filename = '\n' + filename + '\n'
pyacdb.acutPrintf(filename)
def print_msg2():#called with 'PY2' command
#using swig wrapper using helper:
pDb2 = pyacdb.acdb_getCurrentDb()
dbstring = str(pDb2) + '\n'
pyacdb.acutPrintf(dbstring)
filename = pyacdb.acdb_getFileName(pDb2) #a C global function
filename = '\n' + filename + '\n'
pyacdb.acutPrintf(filename)
..............................
It seems that I'm getting the same pointer for both methods, I just can't use it to call class methods of the C++ class wrapper??
Here's the output -
Command: PY1 <----- class wrapper output >
PyArxError: Failed to call Python callback. <---- this is from the interpreter dll Command: PY2 <------ using helper/s output >
C:\Documents and Settings\Mick\My Documents\Drawing1.dwg
Hoping this may shed some light on the problem, thanks.
Mick.
if (Nabble.searchterms != null && Nabble.searchterms.length > 0) { Nabble.hilt(Nabble.searchterms, Nabble.get("nabble.msgtxt19411391")); }
//Nabble.gquery = 'test'; //Nabble.topicDumpSearch = true; if (Nabble.gquery!=null) { if (Nabble.topicDumpSearch) { Nabble.get('nabble.searchResults').innerHTML = '
Other threads matching \"'+Nabble.gquery+'\":
'+ '
Search Nabble for "'+Nabble.gquery+'"' ); } } if( Nabble.prev ) Nabble.writeReturnToLink(Nabble.prev);
≪ Search Nabble for "python autocad"
Free embeddable forum powered by Nabble Forum Help
(function(){ if( Nabble.cur ) { var t = Nabble.get( "nabble.i" + Nabble.cur ); if( t ) { t.style.visibility = "visible"; } } if( Nabble.gquery!=null ) { var t = Nabble.get("nabble.searchQuery"); t.value = Nabble.gquery; Nabble.selectOption(Nabble.get("nabble.searchSelect"),"n"); if( !Nabble.notRed ) { t.className += "error-message"; t.style.borderStyle = "solid"; t.style.borderWidth = "3px"; t.style.backgroundColor = Nabble.currentStyle(Nabble.get('nabble')).backgroundColor; } } })(); Nabble.analytics(); _qoptions={ qacct:"p-34EL1DZyJypTI" };
Nabble.addCssRule(document.styleSheets[0],'.nabble a:link','color:'+document.linkColor); Nabble.addCssRule(document.styleSheets[0],'.nabble a:visited','color:'+document.vlinkColor);
if (!Nabble.isEmbedded) { document.write('Nabble | Old Nabble1'); } else if (false) { document.write('Back to the forum'); } Nabble | Old Nabble1 | Software ≫ SourceForge ≫ SWIG ≫ swig-user Login : Register
Nabble.userHeader(3366);
Swig Python/Autocad binding
View: Threaded Chronologically All Messages Nabble.selectOption(Nabble.get("nabble.viewSelect"),Nabble.tview); New views 9 Messages ? Rating Filter: 0 1 2 3 4 5 Alert me if( Nabble.user == 799921 || Nabble.user == 77858) { document.writeln('Move thread'); }
Swig Python/Autocad binding document.write(Nabble.ratingStars(3));
by document.write(' Mick Duprez document.write(''); document.write(Nabble.formatDateLong(new Date(1219651075018))); Aug 25, 2008; 04:57pm :: Rate this Message: - Use ratings to moderate (?)
document.writeln('Reply | '); Reply | Reply to Author if( Nabble.user == 799921 ) { document.writeln('| Edit'); document.writeln('| Delete'); } else if( Nabble.user == 77858 ) { document.writeln('| Delete'); } document.writeln('| Print'); | Print | View Threaded | Show Only this Message
Hi All,
I've been trying to wrap the AutoCAD ARX api (ARX is the app's C++ SDK) with some success but am stumped at the moment with what may be a simple problem.
The wrapper seems to work with some methods but not others.
For instance, I can call a wrapped global function no problem, this was the first test to see if the wrapper was going to work. Now that I've wrapped some C++ classes I've hit a snag, I seem to be able to call a simple method from a class but when I try to debug other methods the breakpoints are not getting hit and I receive an error and the method in Python fails.
As I have no debugging from Python i can print what the pyobject is to the autocad command line using str(object) and I am indeed getting a pointer to a proxy object, it's functions are just not getting called. The functions are overloaded and swig has produced the code to decide which one to call and I have set bp's at each one and none get hit.
Any help greatly appreciated, if you need the solution or for me to post some code (the .i file is quite large but I can post bit's you might need to look at), just let me know.
Thanks,
Mick.
Some set up details -
winXP SP2
VS2005 std SP1
Python 2.5.2
SWIG 1.3.36
AutoCAD 2008 SDK
google_protectAndRun("render_ads.js::google_render_ad", google_handleError, google_render_ad); if (Nabble.searchterms != null && Nabble.searchterms.length > 0) { Nabble.hilt(Nabble.searchterms, Nabble.get("nabble.msgtxt19139435")); }
Re: Swig Python/Autocad binding document.write(Nabble.ratingStars(3));
by document.write(' Mick Duprez document.write(''); document.write(Nabble.formatDateLong(new Date(1219652839081))); Aug 25, 2008; 05:27pm :: Rate this Message: - Use ratings to moderate (?)
document.writeln('Reply | '); Reply | Reply to Author if( Nabble.user == 799921 ) { document.writeln('| Edit'); document.writeln('| Delete'); } else if( Nabble.user == 77858 ) { document.writeln('| Delete'); } document.writeln('| Print'); | Print | View Threaded | Show Only this Message
Just thought I'd add how the project is set up.
In autocad I've made an arx(dll) plug in that embeds the Python interpreter. From here I have some functions that register python script callbacks in a PyDict which are called from autocad commands.
The callbacks are python methods with no args and they all go through the same C++ static function to call the method. My autocad code catches the command from the user, searches the dict for the command string (key) whose value is the python script callback and it's pushed through the C++ function to execute using the C Python api.
I import my wrapped module/s into the script with the callback and interact with the main app as required then return back to the main app.
hope that gives some further insight,
cheers.
if (Nabble.searchterms != null && Nabble.searchterms.length > 0) { Nabble.hilt(Nabble.searchterms, Nabble.get("nabble.msgtxt19139804")); }
Re: Swig Python/Autocad binding document.write(Nabble.ratingStars(3));
by document.write(' Mick Duprez document.write(''); document.write(Nabble.formatDateLong(new Date(1219922939810))); Aug 28, 2008; 08:28pm :: Rate this Message: - Use ratings to moderate (?)
document.writeln('Reply | '); Reply | Reply to Author if( Nabble.user == 799921 ) { document.writeln('| Edit'); document.writeln('| Delete'); } else if( Nabble.user == 77858 ) { document.writeln('| Delete'); } document.writeln('| Print'); | Print | View Threaded | Show Only this Message
No takers yet :)
Ok, another question that may even solve a big part of the problem.
I've read here and other places that when embedding an interpreter I should also compile the swig interface with it. Is this the correct way?
I've tried both with no real difference, the only thing is I can't call SWIG_init() (which I think is key here) as my wrapper file doesn't have a header file, should I just create one and add it to the interface file so I can 'include' it in my dll entry point file?
I have done extensive searching here and elswhere but a lot of posts glaze over some details that some long time users take for granted (or I still don't understand), so, if someone can give me a basic setup/direction of how I should be doing this that would be greatly appreciated.
My goal is to create a dll that's imported into the main application and embeds a Python interpreter. Using the swig wrapped api I'd like to write scripts callable form the main application through this dll, this part I have worked out fine, it's my interface/glue code with the swig wrapped api that's not working so far.
Thanks,
cheers,
Mick.
if (Nabble.searchterms != null && Nabble.searchterms.length > 0) { Nabble.hilt(Nabble.searchterms, Nabble.get("nabble.msgtxt19198652")); }
Re: Swig Python/Autocad binding document.write(Nabble.ratingStars(3));
by document.write(' mark gossage document.write(''); document.write(Nabble.formatDateLong(new Date(1220237901000))); Sep 01, 2008; 11:58am :: Rate this Message: - Use ratings to moderate (?)
document.writeln('Reply | '); Reply | Reply to Author if( Nabble.user == 220699 ) { document.writeln('| Delete'); } else if( Nabble.user == 77858 ) { document.writeln('| Delete'); } document.writeln('| Print'); | Print | View Threaded | Show Only this Message
>
> No takers yet :)
>
> Ok, another question that may even solve a big part of the
> problem.
>
> I've read here and other places that when embedding an
> interpreter I should
> also compile the swig interface with it. Is this the
> correct way?
>
> I've tried both with no real difference, the only thing
> is I can't call
> SWIG_init() (which I think is key here) as my wrapper file
> doesn't have a
> header file, should I just create one and add it to the
> interface file so I
> can 'include' it in my dll entry point file?
>
> I have done extensive searching here and elswhere but a lot
> of posts glaze
> over some details that some long time users take for
> granted (or I still
> don't understand), so, if someone can give me a basic
> setup/direction of how
> I should be doing this that would be greatly appreciated.
>
> My goal is to create a dll that's imported into the
> main application and
> embeds a Python interpreter. Using the swig wrapped api
> I'd like to write
> scripts callable form the main application through this
> dll, this part I
> have worked out fine, it's my interface/glue code with
> the swig wrapped api
> that's not working so far.
>
> Thanks,
> cheers,
> Mick.
>
...[show rest of quote]
Hello Mick,
Where to start....
As far as I read from you post, what you a looking to do is to embed a python interpreter into your C/C++ Autocad application, and then have it call a bunch of the Autocad functions.
This is two seperate matters: 1. embedding the python interpreter, 2. calling Autocad functions.
SWIG will easily perform 2 for you, but on part 1, you have to DIY.
Dealing with part 2 first: what you do is create a .i file with all your functions to wrapper in that, and feed to SWIG. It will then create the bindings for you. Job done.
For part 1, this is harder. The python documentation on embedding is not very good. I you believe: http://davidf.sjsoft.com/mirrors/mcmillan-inc/embed.html I guess python is not meant for this task.
However http://www.linuxjournal.com/article/8497 does give a very simple example of embedding which you could work with.
To add the SWIG bindings to this is just one more line of code.
Expanding one of the examples from the previous article:
void exec_pycode(const char* code)
{
Py_Initialize();
Example_init(); // call SWIG module
PyRun_SimpleString(code);
Py_Finalize();
}
But the whole business of embedding Python is not so easy to do. I would start by just adding a simple embed (as this) and try to call some python from Autocad, then try adding one autocad function to see if you can do it.
Hope this helps,
Mark
-------------------------------------------------------------------------
This SF.Net email is sponsored by the Moblin Your Move Developer's challenge
Build the coolest Linux based applications with Moblin SDK & win great prizes
Grand prize is a trip for two to an Open Source event anywhere in the world
http://moblin-contest.org/redirect.php?banner_id=100&url=/
_______________________________________________
Swig-user mailing list
Swig-user@...
https://lists.sourceforge.net/lists/listinfo/swig-user
if (Nabble.searchterms != null && Nabble.searchterms.length > 0) { Nabble.hilt(Nabble.searchterms, Nabble.get("nabble.msgtxt19248314")); }
Re: Swig Python/Autocad binding document.write(Nabble.ratingStars(3));
by document.write(' Mick Duprez document.write(''); document.write(Nabble.formatDateLong(new Date(1220243199877))); Sep 01, 2008; 01:26pm :: Rate this Message: - Use ratings to moderate (?)
document.writeln('Reply | '); Reply | Reply to Author if( Nabble.user == 799921 ) { document.writeln('| Edit'); document.writeln('| Delete'); } else if( Nabble.user == 77858 ) { document.writeln('| Delete'); } document.writeln('| Print'); | Print | View Threaded | Show Only this Message
Thanks Mark,
I have the Python interpreter embeded ok and I have manually wrapped some code with little problem, I can use the COM api from Python scripts at the moment and I have the callbacks all organised.
I have successfully compiled a SWIG module and I can get a global method to work, but if I try to call a class method I get an error and my callback fails to finish the task.
I have set break points in the SWIG code for debugging but they are not being hit, the global method gets hit ok, just not the class methods.
There is nothing real special about the C++ classes I'm wrapping and SWIG is generating what looks like the class interface code ok, maybe I need an extra swig preprocessing helper or something(?).
I'll do some more study tonight and see if I can spot anything else I'm missing.
Cheers,
Mick.
PS. As I only have limited debugging on the python side, I am using a print statement to see if I have created an object in Python, it's seems as though I am but I don't think I'm getting one on the C++ side, and that's where the problem lies I think.
if (Nabble.searchterms != null && Nabble.searchterms.length > 0) { Nabble.hilt(Nabble.searchterms, Nabble.get("nabble.msgtxt19248754")); }
Re: Swig Python/Autocad binding document.write(Nabble.ratingStars(3));
by document.write(' Mick Duprez document.write(''); document.write(Nabble.formatDateLong(new Date(1220869144162))); Sep 08, 2008; 07:19pm :: Rate this Message: - Use ratings to moderate (?)
document.writeln('Reply | '); Reply | Reply to Author if( Nabble.user == 799921 ) { document.writeln('| Edit'); document.writeln('| Delete'); } else if( Nabble.user == 77858 ) { document.writeln('| Delete'); } document.writeln('| Print'); | Print | View Threaded | Show Only this Message
So far I've tried just about everything, features, inline helpers and read the doc's more than a few times, I just can't get something that seems/claims to be so simple to do anything useful. The only thing that seems to work is if I wrap what I need into %inline helper functions.
Here is part of one of the more complicated classes, is there something obvious I'm missing here?
The only time you create a new object is if you're creating a new file, hence the only ctor.
Normally you wold use a global function to get the 'active' db object then use its methods add/remove/modify obects, when I call getBlockTable below it fails, if I try to unload the dll hosting the interpreter it crashes the main app.
class AcDbDatabase: public AcRxObject, public AcHeapOperators
//
// A class whose instances represent an entire DWG file,
// aka database itself.
//
{
public:
virtual AcRxClass* isA() const;
static AcRxClass* desc();
static AcDbDatabase* cast(const AcRxObject* inPtr)
{ return ((inPtr == NULL) || !inPtr->isKindOf(AcDbDatabase::desc()))
? NULL : (AcDbDatabase*)inPtr; };
// constructor & destructor
AcDbDatabase(bool buildDefaultDrawing = true,
bool noDocument = false);
virtual ~AcDbDatabase();
// a typical call to get another object I've wrapped also:
Acad::ErrorStatus getBlockTable (AcDbSymbolTable*& pTable,
AcDb::OpenMode mode);
.... and so on.
Here's some python code, please excuse it :) -
def addline():
try:
sp = pyacdb.AcGePoint3d(30.0,45.0,0.0)
ep = pyacdb.AcGePoint3d(120.0,120.0,0.0)
line = pyacdb.AcDbLine(sp,ep)
pyacdb.acutPrintf ('\nIn addline6.1 ...\n') #this works fine, global function
pDb = pyacdb.acdbWorkingDatabase()
pyacdb.acutPrintf ('\nIn addline7...\n') #I'm getting to here....
pDb.getBlockTable(pBt, AcDb.kForRead)
pyacdb.acutPrintf ('\nIn addline7.1..\n') #not making it here though!!!
pBt.getAt('*Model_Space',pBtr,AcDb.kForWrite)
pyacdb.acutPrintf ('\nIn addline7.2..\n')
pBt.close
pyacdb.acutPrintf ('\nIn addline8...\n')
id = pyacdb.AcDbObjectId()
pyacdb.acutPrintf ('\nIn addline9...\n')
pBtr.appendAcDbEntity(id,line)
pyacdb.acutPrintf ('\nIn addline10...\n')
pBtr.close
pyacdb.acutPrintf ('\nwOOOOt!!...\n')
except:
msg = "Unexpected error:" + sys.exc_info()[0]
pyacdb.acutPrintf (msg)
raise
and here's the main part of the calling method in the interpreter hosting dll -
// grab the callback from the PyDict and call it:
PyObject *arglist;
PyObject *result, *func;
arglist = Py_BuildValue("()");
func = PyDict_GetItemString(pCmdDict,pyStr);
if (PyCallable_Check(func))
{
result = PyEval_CallObject(func, arglist);
}
Py_DECREF(arglist);
if (result == NULL)
{
acutPrintf(_T("PyArxError: Failed to call Python callback.\n"));
return;
}
Py_DECREF(result);
if(pyStr)
{
free(pyStr);
}
What I do here is, when I load the interpreter I call into an 'initialiser' .py file which calls an embedded method using straight python extension code to load method callbacks into a dict object, the application calls a method callback in the dict by it's string key as a command using the code above.
This works pretty well so far (all though it needs more error handling to stop trashing the host's memory), it seems as if I'm either loosing my pointer to the database object or it's not 'really' creating one??
I feel I'm just one step away but my eyes have all but glazed over from all this study and testing to no avail. Swig is wrapping as much or as little as I need with little trouble, it's just not working as I would have hoped.
Thank you,
Mick.
if (Nabble.searchterms != null && Nabble.searchterms.length > 0) { Nabble.hilt(Nabble.searchterms, Nabble.get("nabble.msgtxt19369352")); }
Re: Swig Python/Autocad binding document.write(Nabble.ratingStars(3));
by document.write(' Steven Hirsch document.write(''); document.write(Nabble.formatDateLong(new Date(1220874578000))); Sep 08, 2008; 08:49pm :: Rate this Message: - Use ratings to moderate (?)
document.writeln('Reply | '); Reply | Reply to Author if( Nabble.user == 804348 ) { document.writeln('| Delete'); } else if( Nabble.user == 77858 ) { document.writeln('| Delete'); } document.writeln('| Print'); | Print | View Threaded | Show Only this Message
On Mon, 8 Sep 2008, Mick Duprez wrote:
> So far I've tried just about everything, features, inline helpers and read
> the doc's more than a few times, I just can't get something that
> seems/claims to be so simple to do anything useful. The only thing that
> seems to work is if I wrap what I need into %inline helper functions.
>
> Here is part of one of the more complicated classes, is there something
> obvious I'm missing here?
> The only time you create a new object is if you're creating a new file,
> hence the only ctor.
> Normally you wold use a global function to get the 'active' db object then
> use its methods add/remove/modify obects, when I call getBlockTable below it
> fails, if I try to unload the dll hosting the interpreter it crashes the
> main app.
...[show rest of quote]
I must be missing something in your sample code. Where's the constructor
for the database object? You are showing code that tries to use the
object, but are not detailing where it comes from and how?
Steve
-
-------------------------------------------------------------------------
This SF.Net email is sponsored by the Moblin Your Move Developer's challenge
Build the coolest Linux based applications with Moblin SDK & win great prizes
Grand prize is a trip for two to an Open Source event anywhere in the world
http://moblin-contest.org/redirect.php?banner_id=100&url=/
_______________________________________________
Swig-user mailing list
Swig-user@...
https://lists.sourceforge.net/lists/listinfo/swig-user
if (Nabble.searchterms != null && Nabble.searchterms.length > 0) { Nabble.hilt(Nabble.searchterms, Nabble.get("nabble.msgtxt19370442")); }
Re: Swig Python/Autocad binding document.write(Nabble.ratingStars(3));
by document.write(' Mick Duprez document.write(''); document.write(Nabble.formatDateLong(new Date(1220905863001))); Sep 09, 2008; 05:31am :: Rate this Message: - Use ratings to moderate (?)
document.writeln('Reply | '); Reply | Reply to Author if( Nabble.user == 799921 ) { document.writeln('| Edit'); document.writeln('| Delete'); } else if( Nabble.user == 77858 ) { document.writeln('| Delete'); } document.writeln('| Print'); | Print | View Threaded | Show Only this Message
Steven Hirsch wrote:
On Mon, 8 Sep 2008, Mick Duprez wrote:
> So far I've tried just about everything, features, inline helpers and read
> the doc's more than a few times, I just can't get something that
> seems/claims to be so simple to do anything useful. The only thing that
> seems to work is if I wrap what I need into %inline helper functions.
>
> Here is part of one of the more complicated classes, is there something
> obvious I'm missing here?
> The only time you create a new object is if you're creating a new file,
> hence the only ctor.
> Normally you wold use a global function to get the 'active' db object then
> use its methods add/remove/modify obects, when I call getBlockTable below it
> fails, if I try to unload the dll hosting the interpreter it crashes the
> main app.
I must be missing something in your sample code. Where's the constructor
for the database object? You are showing code that tries to use the
object, but are not detailing where it comes from and how?
Steve
...[show rest of quote]
Hi Steve,
here's the constructor/destructor -
// constructor & destructor
AcDbDatabase(bool buildDefaultDrawing = true,
bool noDocument = false);
virtual ~AcDbDatabase();
At most times you wouldn't need to create a db object as it already exists but you can get a pointer to it using some global functions, the acdbWorkingDatabase() method in the python script is a wrapped helper that 'is' getting called. the eg.
pDb = pyacdb.acdbWorkingDatabase() # get a pointer to a pDb (AcDbDatabase) object
These appear to be working when stepping through code in the debugger but when I call a method on the db object it isn't entering the swig wrapper code and my break points are not being hit.
I wouldn't think you would need an empty/default ctor if the db already existed and I'm not sure how the hosting app would respond creating an object without the default param's?
I did read somewhere though about swig making a new object that then uses a copyctor to put the pointer in but I don't think the host app would like that, does swig do this for 'every' class object being wrapped?
thanks.
Mick.
if (Nabble.searchterms != null && Nabble.searchterms.length > 0) { Nabble.hilt(Nabble.searchterms, Nabble.get("nabble.msgtxt19380559")); }
Re: Swig Python/Autocad binding document.write(Nabble.ratingStars(3));
by document.write(' Mick Duprez document.write(''); document.write(Nabble.formatDateLong(new Date(1221045819290))); Sep 10, 2008; 08:23pm :: Rate this Message: - Use ratings to moderate (?)
document.writeln('Reply | '); Reply | Reply to Author if( Nabble.user == 799921 ) { document.writeln('| Edit'); document.writeln('| Delete'); } else if( Nabble.user == 77858 ) { document.writeln('| Delete'); } document.writeln('| Print'); | Print | View Threaded | Show Only this Message
Ok, a bit more testing revealed I can call a method if I wrap the c++ code into C helper functions, the C++ class functions are still not working.
Here's my code in the interface file for the helper functions, these work fine, the C++ code is as per the earlier post (or a typical class).
.....................
%inline {
AcDbDatabase* acdb_getCurrentDb()
{
AcDbDatabase* pDb;
pDb = acdbHostApplicationServices()->workingDatabase();// api func that returns active db*
return pDb;
}
}
%inline {
const ACHAR* acdb_getFileName(AcDbDatabase* pDb)
{
const ACHAR* filename;
pDb->getFilename(filename);// get the db*'s filename
return filename;
}
}
int acutPrintf(const ACHAR* format, ...); // function to print string output to autocad command line/prompt
......................
these are the 2 python script functions I call that grab the current database object pointer and then get it's filename member variable.
.........................
def print_msg1(): #called with 'PY1' command
#using swig wrapper, no helper:
pDb1 = pyacdb.acdbWorkingDatabase()
dbstring = str(pDb1) + '\n'
pyacdb.acutPrintf(dbstring)
filename = ' '
pDb1.getFilename(filename) #call a C++ member function, fails here!!!!
filename = '\n' + filename + '\n'
pyacdb.acutPrintf(filename)
def print_msg2():#called with 'PY2' command
#using swig wrapper using helper:
pDb2 = pyacdb.acdb_getCurrentDb()
dbstring = str(pDb2) + '\n'
pyacdb.acutPrintf(dbstring)
filename = pyacdb.acdb_getFileName(pDb2) #a C global function
filename = '\n' + filename + '\n'
pyacdb.acutPrintf(filename)
..............................
It seems that I'm getting the same pointer for both methods, I just can't use it to call class methods of the C++ class wrapper??
Here's the output -
Command: PY1 <----- class wrapper output
PyArxError: Failed to call Python callback. <---- this is from the interpreter dll Command: PY2 <------ using helper/s output
C:\Documents and Settings\Mick\My Documents\Drawing1.dwg
Hoping this may shed some light on the problem, thanks.
Mick.
if (Nabble.searchterms != null && Nabble.searchterms.length > 0) { Nabble.hilt(Nabble.searchterms, Nabble.get("nabble.msgtxt19411391")); }
//Nabble.gquery = 'test'; //Nabble.topicDumpSearch = true; if (Nabble.gquery!=null) { if (Nabble.topicDumpSearch) { Nabble.get('nabble.searchResults').innerHTML = '
Other threads matching \"'+Nabble.gquery+'\":
'+ '
Search Nabble for "'+Nabble.gquery+'"' ); } } if( Nabble.prev ) Nabble.writeReturnToLink(Nabble.prev);
≪ Search Nabble for "python autocad"
Free embeddable forum powered by Nabble Forum Help
(function(){ if( Nabble.cur ) { var t = Nabble.get( "nabble.i" + Nabble.cur ); if( t ) { t.style.visibility = "visible"; } } if( Nabble.gquery!=null ) { var t = Nabble.get("nabble.searchQuery"); t.value = Nabble.gquery; Nabble.selectOption(Nabble.get("nabble.searchSelect"),"n"); if( !Nabble.notRed ) { t.className += "error-message"; t.style.borderStyle = "solid"; t.style.borderWidth = "3px"; t.style.backgroundColor = Nabble.currentStyle(Nabble.get('nabble')).backgroundColor; } } })(); Nabble.analytics(); _qoptions={ qacct:"p-34EL1DZyJypTI" };
댓글
댓글 쓰기