Tuesday, February 15, 2005

Appendix A - Debug versus Release

ObjectARX and ObjectBDX applications could be compiled using Debug or Release configurations. For those who are beginners with programming is very important to know what are the differences between these two types of compilation.

When your are developing an application you will pass through several steps before it reaches the deployment phase. These steps are very important to detect bugs inside your application, correct them and make your application as much secure as you can.

When you are on the phase prior to deployment you will probably need to debug your code. The debug tool, using a simplistic point of view, is just a way to follow your application execution mapping what is happening on the execution environment to the corresponding line at your source code. This tool is powerful and essential to troubleshoot your application.

To make this happen, Visual Studio compiles your code adding debug information that will allow it to map events to your source code, show variables, show memory stack, code flowing and much more. This is pretty handy and helps a lot! Matter of fact you can't live without the debug tool. Due that, your resulting application is linked with Debug versions of extensions you are using like MFC. If you deploy your Debug version to your clients they will face trouble to load it because the probably will not have those debug libraries available.

Suppose your application uses the mfc42.dll which is a common situation. When you compile your application using the Debug type it will use the mfc42d.dll which is the debug version of the original DLL. When your client tries to load the application, Windows will search for the required DLL (debug version) which does not exist in that machine and will fail to load.

Worst than deploy Debug version is do ship the debug version of those DLLs your application needs. These DLLs are for development purposes only. Please, don't do that!
There are much more issues involved on this but basically you should follow the following ground rules:
  • Use the Debug compilation for development purposes only;
  • From time to time compile and test your application with Release version because Debug compilation is more robust and may hide some runtime errors that Release version won't;
  • Don't ship debug versions of Windows or third-party libraries except for debug purposes;
  • Use the _DEBUG symbol directive to isolate parts of your code that are only interesting when debugging. For instance, some trace messages are very interesting to you but users will hate to keep seeing them every time.

At the last, debug compiled applications has a higher file size (sometimes almost 5 times greater than Release version).

61 comments :

Anonymous said...

Hi Fernando,
Thank you for the articles. You are a good hand at this.

Valery

Anonymous said...

Olá Fernando
Sou um desenhador português e utilizo diariamente o Autocad (neste momento na versão 2006) usualmente crio rotinas em autolisp/visual lisp para um aumento de productividade na empresa que trabalho e até para outras empresas e desenhadores, mas neste momento estou a tentar compreender o objectARX para criar aplicações mais poderosas e mais rápidas, o que eu gostava de saber é se existe uma versão em português do seu "ObjectArx for Dummies"

Cumprimentos
Pedro Ferreira

http://pwp.netcabo.pt/pedro_ferreira

Anonymous said...

thank you!!

Anonymous said...

tenta ir a este link: (é uma verção traduzida do website)

http://translate.google.com/translate?hl=pt-PT&sl=en&u=http://arxdummies.blogspot.com/&sa=X&oi=translate&resnum=1&ct=result&prev=/search%3Fq%3DObjectArx%2Bfor%2BDummies%26hl%3Dpt-PT%26lr%3D

Anonymous said...

This has been a very helful course, you should turn it into a book.

Anonymous said...

I canť debug in ARX. If I try ti, Compiler say me, "Debugging information fo "acad.exe" cannot be found od does not match. No symbols loaded. Do you want to continue debugging ?

Thanks for help.
michal@hadraba.cz

Fernando Malard said...

Hi michal,

The ObjectARX SDK does not provide the debug modules for AutoCAD debug. This does not avoid you to fully debug your code but you won't be able to step into specific ObjectARX source code.

Just ignore this message and proceed with your debug process.

Regards.

filipe.scur said...

Fernando,

Tudo bem? Cara estou tentando "debugar" uma aplicação ARX mas não tem jeito. Não consigo. Instalei o ARX Wizard e mesmo assim não debuga. Se eu marco a opção "Enable unmanaged code debugging", aparece um erro "No symbols loaded", e como você falou, eu clico em continuar, mas quando eu uso o NETLOAD, não carrega a aplicação. Se eu desmarco a opção, não aparece erro quando tento debugar, mas aparece quando tento utilizar algum comando da aplicação. Não sei mais o que fazer, tem alguma idéia do que pode ser?????

Obrigado

Fernando Malard said...

Filipe,

Quais a versões do AutoCAD/VStudio vocês está utilizando?

Tentou depurar no modo Attach? Faça assim:
- Compile o código em DEBUG;
- Abra o AutoCAD (sem ser com F5 do VStudio);
- Quando o AutoCAD estiver ok, vá no VStudio e escolha: Tools > Attach to Projet
- Clique no botão SELECT e escolha os modos de depuração ou deixe no automático
- Veja na lista o módulo acad.exe, selecione ele e clique em ATTACH.

Provavelmente desse modo sua depuração irá funcionar.

Abraços,
Fernando.

Anonymous said...

Hi Fernando,
Thank for the course. It´s very interesting.
I have downloaded Autocad Map 3d 2010 and ObjetARX from AutoDesk home page.
What VC++ or VC++.net version I need for that?
Thanks, Peter

Fernando Malard said...

Hello Peter,

Either 2010 or 2011 AutoCAD versions and their verticals require VS2008.

If you compile with ObjectARX 2010 it will work on both versions.

Regards.

Anonymous said...

Hi,
We read your blog.It's realy nice.
But,I have an question that how to read a line using ObjectARX from AutoCAD.
please give me answer as early as possible.
Thanks in advance.

Fernando Malard said...

Hello smita,

A Line is represented inside AutoCAD API as an AcDbLine class.

From the user selection you can get the AcDbObjectId and open it as an AcDbEntity then casting to AcDbLine.

Once you cast it all specific AcDbLine methods and properties will be available.

Keep in mind if you need to open just for retrieve values you will use kForRead and when need to modify it use kForWrite.

Take a look at classes 6 and 8.

Regards.

Anonymous said...

Hi,
Thanks for your reply.
But I want to know how to read a line from .dwg file.
can u send me a sample code???
plz help me,I want u'r help in my project.
Thanks in advance.
Smita.

Fernando Malard said...

smita,

Could you please explain in details what do you mean with "read a line"?

Are you trying to open an existing DWG and read all lines inside it for some specific purpose?

Are you trying to create new lines into an existing DWG?

Regards,

Anonymous said...

Hi,
Yes,We are trying to open an existing DWG and read all lines inside it for some specific purpose.

Plz send me a sample code.

Smita.

Anonymous said...

Hi,
can u send me a reply as early as possible.
as i told u we r using ObjectARX in our BE project and we r just waiting for u'r reply.
so please help us.
Thanks.

Fernando Malard said...

Hi smita,

The sample you want can be found inside ObjectARX SDK:

\ObjectARX 2010\samples\database\testdb_dg

It will show you how to create, open and iterate over the DWG's BlockTableRecords.

Just remember to test your opened entities by doing a cast() to AcDbLine* pointers.

Regards.

Anonymous said...

Hi,
Thanks again for your reply.
Which are the good reference books for ObjectARX.
Actally,we doesn't get exact way for our project.
Can you tell me the functions for reading dimensions of line from database using ObjectARX.
Sorry for too many quesions.
Thanking you.
Smita.

Fernando Malard said...

Hi smita,

There are a couple of books inside Amazon.com but I think they are not up to date.

If your project requires complex support I would recommend your company to register as ADN member. This will give you ability to submit support requests direct to the ADN team and also participate on local/web training about ObjectARX API.

You can easily calculate the length of a line by simply getting its start and end points and doing:

AcGePoint3d p1 = pLine->startPoint();

AcGePoint3d p2 = pLine->endPoint();

double dDist = p1.distanceTo(p2);

Regards,
Fernando.

Anonymous said...

Hi,
can you tell me how to set project properties in VC++ when i want to take project type as "windows forms application"?
Thanking you.
smita.

Fernando Malard said...

smita,

If you are asking about creating a ObjectARX .NET application with Windows Forms inside, you need to create either a VB.NET or C# project by using ARXWizard.

This wizard, which can be found inside your ObjectARX\Utils folder, will create new project templates inside your Visual Studio.

For ObjectARX managed API I strongly recommend you to take a look at my Kean's Blog:

http://through-the-interface.typepad.com/

Good luck!

Anonymous said...

Hi,
I don't want ObjectARX .NET application with Windows Forms,I want ObjectARX VC++ application with windows forms,so what are properties i can set?
Thanking you.
Smita.

Anonymous said...

Hi,
I have a doubt.

I Have drawn a line in test1.dwg
(10,10)(60) with angle 0 is input to my program.
but my code give me following output:-

Command: check
start x:0
start y:0
end x:900835553
end y:79184083
classname: AcDbLine


so,my doubt is how those end & start points x&y co-ordinates are calculated.


Code:-




AcDbDatabase *pDb = new AcDbDatabase(Adesk::kFalse);

// The AcDbDatabase::readDwgFile() function
// automatically appends a DWG extension if it is not
// specified in the filename parameter.
//
if(Acad::eOk != pDb->readDwgFile(_T("c:\\test1.dwg")))
return;

// Open the model space block table record.
//
AcDbBlockTable *pBlkTbl;
pDb->getSymbolTable(pBlkTbl, AcDb::kForRead);

AcDbBlockTableRecord *pBlkTblRcd;
pBlkTbl->getAt(ACDB_MODEL_SPACE, pBlkTblRcd,
AcDb::kForRead);
pBlkTbl->close();

AcDbBlockTableRecordIterator *pBlkTblRcdItr;
pBlkTblRcd->newIterator(pBlkTblRcdItr);

AcDbEntity *pEnt;
AcDbLine *l1;
for (pBlkTblRcdItr->start(); !pBlkTblRcdItr->done();
pBlkTblRcdItr->step())
{
pBlkTblRcdItr->getEntity(pEnt,
AcDb::kForRead);
l1=AcDbLine::cast(pEnt);
AcGePoint3d p1=l1->startPoint();
acutPrintf(_T("start x:%d\n"),p1.x);
acutPrintf(_T("start y:%d\n"),p1.y);
AcGePoint3d p2=l1->endPoint();
acutPrintf(_T("end x:%d\n"),p2.x);
acutPrintf(_T("end y:%d\n"),p2.y);
acutPrintf(_T("classname: %s\n"),
(pEnt->isA())->name());
pEnt->close();
}
pBlkTblRcd->close();
delete pBlkTblRcdItr;
delete pDb;
Thanking you,
Smita.

Anonymous said...

Hi,
I am really very sorry.
I got my solution for the code which I have sent in previous comment.
Thank you very much.
Smita

Fernando Malard said...

smita,

I would recommend you to use C# for several reasons I won't list here.

VC.NET has a terrible syntax and the additional problem of dealing with pointers. You should be much more comfortable with C#.

Take a look at Kean's Blog to see how many samples and good articles you can find about C# and AutoCAD:

http://through-the-interface.typepad.com/

Regards.

Anonymous said...

Hi,
Actually I don't want .net and c#.I want properties of vc++ for windows form application.Please give reply on my account.
Smita

Anonymous said...

Hi,
I have tried u'r following code from class 5,


ads_name na;
AcDbObjectId id;
acedSSGet(_T("L"),NULL,NULL,NULL,na);
acdbGetObjectId(id,na);
AcDbEntity* pEnt = NULL;
if (acdbOpenObject(pEnt, id, AcDb::kForRead) == Acad::eOk) {
if (pEnt->colorIndex() != 3) {
pEnt->upgradeOpen();
pEnt->setColorIndex(3);
}
else {
acutPrintf(_T("\nEntity already has color=3"));
}
pEnt->close();
}








but,i got error at acdbOpenObject.
error is:-
fatal error:Unhandled access violation reading 0x0005 Exception at 620663e4h.
Can u help me.
Thanking you.
Smita.

Fernando Malard said...

Smita,

There shouldn't be any problem with the code. It seems that the entity you are trying to edit has an invalid open state.

Try to create a sample application with just this code, create an entity manually inside AutoCAD and execute the method. The color will change as expected.

In regards to your other question, I think you are mixing the concepts. You cannot use Windows forms without having at least a Mixed mode DLL into your project.

The result of C#, VB.NET or VC.NET compilation is always a intermediate language code so no big difference among them.

If you plan to use unmanaged C++ code with ObjectARX you cannot access Windows Forms classes natively.

The current trend is:

- Create all your UI with WPF into managed modules (no matter if it is created with C# or VB.NET);
- Create a mixed mode DLL to allow you to communicate between the managed and unmanaged worlds;
- Create your pure C++ code with ObjectARX classes that are not exposed through .NET API.

This scenario can be adjusted as you will but it still not clear for me what you are trying to create.

Regards.

Anonymous said...

Hi,
How to add component add-in or plug-in into autocad using ObjectARX or ObjectDBX?
Thanking you,
Smita.

Fernando Malard said...

Smita,

There are several ways to do that:

-Use the ARX command to load/unload either ARX or DBX modules;

-Use APPLOAD command to do the same but also to add the module to "Startup suite" which is a list of applications AutoCAD will load during its startup process;

-Use DEMAND LOADING mechanism which consist of some Registry entries that will tell AutoCAD when to load your application like: AutoCAD Startup, Command Invocation, etc.

All these procedures are well described into the ARX SDK manual. Pay attention to one special aspect which is the dependency among your modules. Basic modules should be loaded first and unloaded last.

So, if you have one main ARX module and several DBX modules the DBX should be loaded prior than the ARX. The unload sequence is the opposite, ARX should be unloaded first and then the DBX.

Regards.

Anonymous said...

Hi,
Can u tell m abt how to display plugin in autocad menubar?
Can u give me a sample code?
Thanking you,
Smita.

Fernando Malard said...

Smita,

There are several options like MENU, TOOLBAR and RIBBON.

All examples can be found into ARX SDK Samples folder.

Regards.

Unknown said...

Hi,

Where i can get Labview Palette?

Thanking You,
kirti

Fernando Malard said...

kirti,

I don't know. There is a sample to demonstrate a Tool Palette creation inside PolySamp. Not sure how it works in details.

Regards.

Anonymous said...

Hi,
Your told program is for adding menus in status bar,but I want to add my menus in menubar.

Like AcApStatusBar class is there any inbuilt class for menubar or like drawingStatusBar function is there any function for menubar.

I refer code from samples->editor->statusbar.

Thanking you,
Smita.

Unknown said...

Hi,
How to read distance conversion table from autocad using objectarx?
Thanking you.
Kirti

Fernando Malard said...

kirti,

"Distance conversion"? What do you mean?

There is a method called acutCvUnit() which converts a distance from one unit system to another.

Also, take a look at:

acdbDisToF()
acdbRToS()

Regards.

SNEHA said...

Hi,
I have to add My X-variable value in static textBox,which has doble datatype.so How can I add this value in the dialogBox?
Thanking You!
Snehal

Fernando Malard said...

SNEHA,

Take a look at the CAcUiNumericEdit class. It does provide the EDIT box functionality but also provide some data validation features.

More information here:
http://docs.autodesk.com/ACDMAC/2011/ENU/ObjectARX%20Reference/CAcUiNumericEdit.html

Regards.

SNEHA said...

hi..
Thank u!
I don't understand how to add CAcUiNumericEdit class into my code for adding my variables.and I want static Box functions only.can u give me any sample code?

Fernando Malard said...

SNEHA,

Take a look at Lab2 and you will have an example on how to use CAcUi classes:

http://arxdummies.blogspot.com/2005/04/lab-2-using-mfc-dialog.html

Regards.

SNEHA said...

Hi,

Where we will find oninitdialog() function?

Thanking You!

Fernando Malard said...

SNEHA,

OnInitiDialog() method is an override from the CDialog class.

You just need to implement it following the standard function signature so it will be called when your dialog starts.

Take a look at MFC documentation about this method and its usage.

Regards.

SNEHA said...

Hi..
How to Change the properties at runtime in vc++?
Thanking you!!
Snehal

Fernando Malard said...

SNEHA,

What properties? Entity's properties like color, layer, etc?

Please be more specific.

Anonymous said...

Hi,
Thank you so much sir,because of only ur dummis we r able to complete our project successfully.
Smita,snehal,kirti,arati.

Fernando Malard said...

Thank you Smita, snehal, kirti and arati.

The Blog's intention is to help people. Glad it helped on your project and I hope you pass this knowledge to other people.

Best regards.

Unknown said...
This comment has been removed by the author.
Fernando Malard said...

Hi Sandhya,

Your code seems to be ok except for one thing.
Where you do the cast() if the entity pointed by the Iterator is not an AcDbLine or any class derive from it, the resulting l1 pointer will be NULL and then all access through this pointer will cause AutoCAD to crash.

After you perform the cast() you need to test the pointer before continue. Something like this:


...

l1=AcDbLine::cast(pEnt);
if (l1 != NULL)
{
AcGePoint3d p1=l1->startPoint();
acutPrintf(_T("start x:%d\n"),p1.x);
acutPrintf(_T("start y:%d\n"),p1.y);

AcGePoint3d p2=l1->endPoint();
acutPrintf(_T("end x:%d\n"),p2.x);
acutPrintf(_T("end y:%d\n"),p2.y);

acutPrintf(_T("classname: %s\n"), (pEnt->isA())->name());
}

...


This should solve your crash.

Regards,

Unknown said...
This comment has been removed by the author.
Fernando Malard said...

Hi Sandhya,

It depends on what you plan to do.
As an object oriented class hierarchy each class implements its own data protocol and also inherit from its parent classes.

AcDbEntity, which is the entity elementar class, does contain entity common information like Layer, LineType, etc.
If you start to go down on its class tree you will find specific classes like AcDbLine which contains specific protocols like startPoint() and endPoint().

Another important class to consider is AcDbCurve which encapsulates all parametric curve methods and properties. Sometimes you can handle your code by accessing this curve class and whatever you do with this pointer is valid across all entities deriving from AcDbCurve. It is pretty handy.

So, unfortunately you need to use cast() operator sometimes to convert the pointer from AcDbEntity down to the class you expect to have. Keep in mind, as I said on the previous post, that the cast() might return NULL in some cases so you always should test the cast() results before proceed.

If you just need to figure out whether a class is some specific class, there is a class descriptor through desc() method. This method can be used together with isKindOf() and isDerivedFrom() methods:

pEnt->isKindOf(AcDbLine::desc());

or

pEnt->isDerivedFrom(AcDbLine::desc());

These class protocol methods are available through every class derived from AcRxClass and I would suggest to read more about it at the ObjectARX User Guide.

Hope it clarifies why you need to use cast().

Regards,

Unknown said...
This comment has been removed by the author.
Fernando Malard said...

You can use the AcDbPolyline class passing the vertexes through their coordinates.
Take a look at this class into the ObjectARX docs.

I would recommend again a detailed read through the User's Guide where you will find a lot of valuable information.

Further, if you take a look at this Blog's, I did an overall course where you can also get more information:

http://arxdummies.blogspot.com.br/p/blog-page.html

Regards,

Unknown said...
This comment has been removed by the author.
Unknown said...
This comment has been removed by the author.
Fernando Malard said...

Hi Sandhya,

Yes, you will need to add some logic to deal with lines with multiple intersections.
A single Line might be crossed by several other lines.

I would say you can do a routine caching the intersection points and the lines involved on that crossing point.
The point can be the key of a Dictionary list and the Value can be a ObjectId array with the IDs on lines involved.
You will have at least 2 lines for each crossing point.

As you may be analysing again the same crossing point coming from another line you need to first check if your Dictionary has this point and then check if that objectId is already stored at the corresponding value.

Anyway, there isn't a direct way of doing what you need.

Regards,

Unknown said...
This comment has been removed by the author.
Fernando Malard said...

Hi Sandhya,

I have created an article about this.
Take a look:

http://arxdummies.blogspot.com.br/2015/08/find-all-acdbline-intersections.html

Hope it helps you to solve your issue.

Regards,

Unknown said...

Hi Fernando,
Error I am facing:
Command: Cannot load assembly. Error details: Autodesk.AutoCAD.Runtime.Exception: eDuplicateKey
at Autodesk.AutoCAD.Runtime.CommandClass.AddCommand(ICommandLineCallable ca, MethodInfo mi)
at Autodesk.AutoCAD.ApplicationServices.AutoCADApplicationHolder.Initialize(Assembly assembly)

Solution I found after going through forums:
You have multiple CommandMethod attributes, or
LispFunction attributes with the same command or function name.

I tried to find attributes or functions but not able to.Can you tell me how can i find these things and change those????

Fernando Malard said...

Hi Gaurav,

Before answer your question, please post and be patient to see it published because the Blog has a Spam filter and all posts must be approved before they are displayed at the Blog. You posted more than 5 times the same question. I have deleted the other posts and assuming this first as the one I will consider.

Back to your question, it seems you are trying to register a command with the same name.
Did you install the AutoCAD.NET Wizard to create the project for you?
It does create a dummy project with samples showing all available command registration options.

Take a look at this page and download the appropriate AutoCAD.NET Wizards accordingly to your AutoCAD version:

http://usa.autodesk.com/adsk/servlet/index?id=1911627&siteID=123112

The AutoCAD.NET Wizards download URLs are the very end of that page.
Hope it helps.