Community
Inventor Programming - iLogic, Macros, AddIns & Apprentice
Inventor iLogic, Macros, AddIns & Apprentice Forum. Share your knowledge, ask questions, and explore popular Inventor topics related to programming, creating add-ins, macros, working with the API or creating iLogic tools.
cancel
Showing results for 
Show  only  | Search instead for 
Did you mean: 

A global transient geometry object?

8 REPLIES 8
SOLVED
Reply
Message 1 of 9
oransen
937 Views, 8 Replies

A global transient geometry object?

I've found myself using this code often:

 

 

// Get the transient geometry object. We'll use this to create pure geometry
CComPtr<TransientGeometry> pTrGeom;
pTrGeom = pApp->TransientGeometry;

 

But I was thinking, once I have pTrGeom can I just declare a global to hold it while my Inventor instance is running?

 

Alternatively I suppose I could have a global function which does this:

 

 

CComPtr<TransientGeometry> GetTransientGeometryPtr()
{
    static CComPtr<TransientGeometry> pTrGeom = NULL ;
if (pTrGeom == NULL) pTrGeom = pApp->TransientGeometry; return (pTrGeom) ; }

 So it reduces to a one-liner. But in COM is that static valid? I know the code is not complete above, but you get the idea.

 

What do other C++ COM programmers do here...?

 

8 REPLIES 8
Message 2 of 9
xiaodong_liang
in reply to: oransen

Hi,

 

Both are fine to me. I perfer to defining it as global directly. It would look more clear.  

Message 3 of 9
oransen
in reply to: xiaodong_liang

Could you give me an example of how you do that?

 

Because when I do it I get an exception when I exit from my program.

 

It seems as if it is not being released properly or maybe released twice, but I'm not COM expert enough to understand the error.

 

Message 4 of 9
jdkriek
in reply to: oransen

What is the exception/error you are getting?

Jonathan D. Kriek
MFG Solutions Engineer
KETIV Technologies, Inc.


Message 5 of 9
oransen
in reply to: jdkriek

Here is the code, I'm new to COM so there may be a supid error in here:

 

 

#include "stdafx.h"


HRESULT ConnectToInventor (CComPtr<Application>& pInvApp)
{
    CLSID InvAppClsid; 
    HRESULT hRes = CLSIDFromProgID (L"Inventor.Application", &InvAppClsid);
    if (FAILED(hRes)) {
        pInvApp = nullptr ;
        return hRes ;
    }

    // See if Inventor is already running...
    CComPtr<IUnknown> pInvAppUnk;
    hRes = ::GetActiveObject (InvAppClsid, NULL, &pInvAppUnk);
    if (FAILED (hRes)) {
        // Inventor is not already running, so try to start it...
        wprintf (L"Could not get hold of an active Inventor , will start a new session\n") ;
        hRes = CoCreateInstance (InvAppClsid, NULL, CLSCTX_LOCAL_SERVER, __uuidof(IUnknown), (void **) &pInvAppUnk);
        if (FAILED (hRes)){
            pInvApp = nullptr ;
            return hRes ;
        }
    }

    // Get the pointer to the Inventor application...
    hRes = pInvAppUnk->QueryInterface (__uuidof(Application), (void **) &pInvApp);
    if (FAILED(hRes)) {
        return hRes ;
    }

    return hRes ;
}

CComPtr<TransientGeometry> pTransGeom = nullptr ;

void InitTransGeomPtr(CComPtr<Application>& pInvApp)
{
    HRESULT hRes = pInvApp->get_TransientGeometry(&pTransGeom);
}

CComPtr<TransientGeometry> GetTransGeomPtr ()
{
    if (pTransGeom == nullptr) {
        wprintf (L"You have not called InitTransGeomPtr\n") ;
    }

    return (pTransGeom) ;
}

static void DoInventorTest ()
{
    CComPtr<Application> pInvApp ;
    HRESULT hRes = ConnectToInventor (pInvApp) ;
    if (FAILED(hRes)) {
        wprintf (L"*** Failed to connect to Inventor application ***\n");
        return ;
    }

    InitTransGeomPtr (pInvApp) ;

    wprintf (L"Hit a key") ;

    _getwch() ;
}

int _tmain(int argc, _TCHAR* argv[])
{
	HRESULT Result = CoInitialize (NULL);

	if (SUCCEEDED(Result))
		DoInventorTest();

	CoUninitialize(); 

	return 0;
}

 When I exit from the program I get the exception shown in the attacched screenshot.

 

All I want to do is be able to have a single transient geometry object/pointer which I init at the start and use throughout the program.

 

Maybe I'm missing a Release or delete or....

 

Message 6 of 9
adam.nagy
in reply to: oransen

Hi,

 

I think it would be a good idea to release the pointer before calling CoUninitialize() - i.e. release the pTransGeom pointer at the end of DoInventorTest(), otherwise the release is only called implicitly when _tmain is returning since the variable is declared globally.

 

Cheers,



Adam Nagy
Autodesk Platform Services
Message 7 of 9
oransen
in reply to: adam.nagy

I thought it could be a "ignorance of com" problem. But how do you release the pointer? the compiler says it is a private function:

 

 

InvSupp.cpp(320): error C2248: 'ATL::_NoAddRefReleaseOnCComPtr<T>::Release' : cannot access private member declared in class 'ATL::_NoAddRefReleaseOnCComPtr<T>'

 

Message 8 of 9
adam.nagy
in reply to: oransen

Message 9 of 9
oransen
in reply to: adam.nagy

I've had a similar problem with the pointer to the Inventor app, it was resolved by setting it to NULL. When I have time I'll try the same with the global transient geometry pointer...

Can't find what you're looking for? Ask the community or share your knowledge.

Post to forums  

Autodesk Design & Make Report