<?xml encoding=”UTF-8″>By Balaji Ramamoorthy
When trying to launch an AutoCAD instance from an external application using CreateInstance, you may get E_NOINTERFACE. In this blog post we will look at some possible reasons and ways to resolve it.
Please note that it is required to build separate 32 and 64 bit versions of your external exe that imports the right version of acax20ENU.tlb. There are GUIDs that are different in 32 and 64 bit versions of the acax20ENU.tlb and so cannot be used interchangeably.
Also, when you build the exe, try providing the absolute path to #import. This will ensure that the right version of the typelibrary gets imported in your project.
For example, use this when building the 32 bit version of your exe :
#import “D:ObjectARX 2016inc-win32acax20ENU.tlb” no_implementation raw_interfaces_only named_guids
and this when building the 64 bit version of your exe :
#import “D:ObjectARX 2016inc-x64acax20ENU.tlb” no_implementation raw_interfaces_only named_guids
If the absolute path is not specified, it can happen that the typelibrary is being picked up from a common location such as “C:Program FilesCommon FilesAutodesk Shared” and which on a 64 bit system is a 64 bit version of the typelibrary. This can cause issue on a 32 bit system and result in E_NOINTERFACE.
Also, from a general COM perspective, the calling thread is required to be a STA. You can have this set using ::CoInitializeEx. Including the following line should help with that :
::CoInitializeEx(NULL, COINIT_APARTMENTTHREADED);
Another reason for E_NOINTERFACE could be a mismatch between the typelibrary being imported and the CLSID used with CreateInstance. For example, if you are importing acax20ENU.tlb, the CLSID must be “AutoCAD.Application.20” which corresponds to AutoCAD 2016.
Here is a sample code to invoke an AutoCAD 2016 instance :
<span>#include</span><span> <span><acadi.h></span><span> </span></span>
<span>#pragma</span><span> <span>warning</span><span> ( <span>disable</span><span> : 4278 )</span></span></span>
<span>// Makes change to the tlb name </span><span> </span>
<span>// based on the AutoCAD version. </span><span> </span>
<span>#import</span><span> <span>"D:\ObjectARX 2016\inc-x64\acax20ENU.tlb"</span><span> \</span></span>
no_implementation raw_interfaces_only named_guids
<span>using</span><span> <span>namespace</span><span> AutoCAD; </span></span>
<span>#pragma</span><span> <span>warning</span><span> ( <span>default</span><span> : 4278 )</span></span></span>
::CoInitializeEx(NULL, COINIT_APARTMENTTHREADED);
CLSID clsidAcad;
HRESULT hr;
hr = ::CLSIDFromProgID(
L<span>"AutoCAD.Application.20"</span><span> , </span>
&clsidAcad);
<span>if</span><span> (FAILED(hr))</span>
<span>{</span>
::MessageBox(
m_hWnd,
_com_error(hr).ErrorMessage(),
L<span>"CLSIDFromProgID Error !"</span><span> ,</span>
MB_OK);
<span>return</span><span> ;</span>
<span>}</span>
OLECHAR* bstrGuid;
::StringFromCLSID(clsidAcad, &bstrGuid);
::MessageBox(
m_hWnd,
bstrGuid,
L<span>"Got CLSID from ProgID !"</span><span> ,</span>
MB_OK);
LPUNKNOWN punkAcad = NULL;
HRESULT hr = S_OK;
IAcadApplicationPtr m_acPtr;
hr = m_acPtr.GetActiveObject(clsidAcad);
<span>if</span><span> (SUCCEEDED(hr))</span>
<span>{</span>
::MessageBox(
m_hWnd,
L<span>"Success_GetActiveObject"</span><span> ,</span>
L<span>"Ok!"</span><span> ,</span>
MB_OK);
m_acPtr->put_Visible(VARIANT_TRUE);
<span>}</span>
<span>else</span><span> </span>
<span>{</span>
::MessageBox(
m_hWnd,
L<span>"GetActiveObject failed, </span><span> </span>
Will <span>try</span><span> CreateInstance !<span>",</span><span> </span></span>
L<span>"GetActiveObject"</span><span> ,</span>
MB_OK);
hr = m_acPtr.CreateInstance(
clsidAcad, NULL, CLSCTX_LOCAL_SERVER);
<span>if</span><span> (SUCCEEDED(hr))</span>
<span>{</span>
::MessageBox(
m_hWnd,
L<span>"Success_CreateInstance"</span><span> ,</span>
L<span>"Ok!"</span><span> ,</span>
MB_OK);
m_acPtr->put_Visible(VARIANT_TRUE);
<span>}</span>
<span>else</span><span> </span>
<span>{</span>
::MessageBox(
m_hWnd,
_com_error(hr).ErrorMessage(),
L<span>"CreateInstance Error !"</span><span> ,</span>
MB_OK);
<span>return</span><span> ;</span>
<span>}</span>
<span>}</span>
<span>if</span><span> (punkAcad) </span>
punkAcad->Release();

Leave a Reply