Home | Contact Us | FAQ | Search & Site Map | Link to Us
Sign In | Join | Other 45 Sites in Network
HomeAnnouncementsFree MagazinesWhite PapersSubmit Content
Discussion GroupsASP.NETWindows FormsLanguages.NET FrameworkVisual Studio.NET
Articles.NET FrameworkASP.NETToolsWindows Forms
.NET DirectoryOpen Source ProjectsUser GroupsWeb Resources
Related Topics
Visual Basic 6SQL ServerMS AccessOther DB ProductsMS Server ProductsMore Topics ...

.NET Forum / Languages / Managed C++ / October 2004

Tip: Looking for answers? Try searching our database.

baffled by exception

Thread view: 
Enable EMail Alerts  Start New Thread
Thread rating: 
Bonj - 12 Oct 2004 12:49 GMT
Hello.
Does anybody know if there is a difference between the way C# calls a COM
object, and the way C++ calls a COM object? And is there anyway to make the
latter emulate the former?

I have a COM object which seemingly can't be instantiated using C++, but can
using C# and VB, and it's driving me insane - I can't work out what's wrong
with it.
It just seems to throw an exception, citing 'User Breakpoint' as the cause
of the exception when any C++ code tried to instantiate it.
If I click 'continue' to the exception when it's in debug mode, it rethrows
it as:
System.Runtime.InteropServices.COMException (0xC0000096): Exception from
HRESULT: 0xC0000096.

But it still throws up the message box when the try..catch is round it!
This COM object, I fully own and the dongle to it is plugged in. Like I say,
I can instantiate this COM object in other languages and I can instantiate
other COM objects using these methods in C++.

Is it possible they could have not wanted you to use it from C++, and can
tell?
Any ideas?

Cheers!
Nicholas Paldino [.NET/C# MVP] - 12 Oct 2004 13:38 GMT
Bonj,

   This seems highly unlikely to me, as the mechanism in .NET ultimately
uses the same mechanism that C++ uses.  Can you show how you are doing it in
.NET and how you are doing it in C++?  Perhaps you are not setting up the
environment or the apartment correctly, and this could be the source of your
problems.

   Hope this helps.

Signature

              - Nicholas Paldino [.NET/C# MVP]
              - mvp@spam.guard.caspershouse.com

> Hello.
> Does anybody know if there is a difference between the way C# calls a COM
[quoted text clipped - 26 lines]
>
> Cheers!
Bonj - 12 Oct 2004 16:45 GMT
>  Can you show how you are doing it in
> ..NET and how you are doing it in C++?
(The library is called MyObjX and the object is called MyObj):

in C++:

#include "stdafx.h"

#using <mscorlib.dll>

using namespace System;
using namespace Interop::MyObjX;
using namespace System::Runtime::InteropServices;

[STAThread]
int _tmain()
{
    MyObjClass* emb = __gc new MyObjClass();
    return 0;
}

//in unmanaged c++ (I first added the myobj.IDL file with the contents of
its type library in COM / object viewer, and then compiled it to produce
myobj_i.c and myobj_h.h

#include <tchar.h>
#include <objbase.h>
#include <comdef.h>
#include "myobj_h.h"

void GetPrediction()
{
    HRESULT hr = CoInitialize(NULL);
    _MyObj* ip;
    try
    {
    hr = CoCreateInstance(CLSID_MyObj, NULL, CLSCTX_INPROC_SERVER, IID__MyObj,
(void**)&ip);
    }
    catch(_com_error e)
    {
        const _TCHAR* s = e.ErrorMessage();
    }
    CoUninitialize();
}

// in C# (which works):

using System;
using MyObjX;

namespace UseEmbCsharp
{
    /// <summary>
    /// Summary description for Class1.
    /// </summary>
    class Class1
    {
        /// <summary>
        /// The main entry point for the application.
        /// </summary>
        [STAThread]
        static int Main(string[] args)
        {
            MyObjX.MyObjClass p = new MyObjClass();
            return 0;
        }
    }
}

>     This seems highly unlikely to me, as the mechanism in .NET ultimately
> uses the same mechanism that C++ uses.

That's what I thought. This is why it baffles me.

>  Perhaps you are not setting up the
> environment or the apartment correctly, and this could be the source of your
> problems.

I can't see what differences there could be - if you can think of any,
please let me know! I've added the [STAThread] attribute to the main of the
MC++ project just like the C# one, and it still doesn't work. I don't know
how to set this for UMC++ - but I think it's more likely to be a security
thing than a threading thing - as the exception that is thrown completely
ignores try..catch handlers, and the COM object is protected with a dongle.
But it is installed completely correctly and legally, and the dongle is
plugged in, and as I say, it works from all languages but ANY breed of
C++.... it's completely weird......
Sigurd Stenersen - 12 Oct 2004 17:27 GMT
> //in unmanaged c++ (I first added the myobj.IDL file with the
> contents of its type library in COM / object viewer, and then
> compiled it to produce myobj_i.c and myobj_h.h

Try using #import and smart pointers instead.

Signature

Sigurd
http://utvikling.com

Bonj - 12 Oct 2004 17:51 GMT
I've done that with still the same exception

> > //in unmanaged c++ (I first added the myobj.IDL file with the
> > contents of its type library in COM / object viewer, and then
> > compiled it to produce myobj_i.c and myobj_h.h
>
> Try using #import and smart pointers instead.
Willy Denoyette [MVP] - 12 Oct 2004 22:26 GMT
And both C++ and MC++ exceptions thrown are the same?
Note that 0XC0000096 isn't a COM exception but a Win32 error code thrown as
a result of a CPU interupt - while trying to execute a privileged
instruction in user mode.
This is weird, and point's to the COM server code itself.

Willy.

> I've done that with still the same exception
>
[quoted text clipped - 3 lines]
>>
>> Try using #import and smart pointers instead.
Bonj - 13 Oct 2004 09:13 GMT
That doesn't surprise me... but how would it be possible to write a COM
component that works successfully from C# and VB, but doesn't work from C++ ??

> And both C++ and MC++ exceptions thrown are the same?
> Note that 0XC0000096 isn't a COM exception but a Win32 error code thrown as
[quoted text clipped - 11 lines]
> >>
> >> Try using #import and smart pointers instead.
Willy Denoyette [MVP] - 13 Oct 2004 21:00 GMT
Well, if the problem was only with C# and MC++, I would think about COM
interop in the CLR. But you also have the same problem using native C++, so
no interop involved :-)

Willy.

> That doesn't surprise me... but how would it be possible to write a COM
> component that works successfully from C# and VB, but doesn't work from
[quoted text clipped - 16 lines]
>> >>
>> >> Try using #import and smart pointers instead.
Nicholas Paldino [.NET/C# MVP] - 12 Oct 2004 13:40 GMT
Bonj,

   This seems highly unlikely to me, as the mechanism in .NET ultimately
uses the same mechanism that C++ uses.  Can you show how you are doing it in
.NET and how you are doing it in C++?  Perhaps you are not setting up the
environment or the apartment correctly, and this could be the source of your
problems.

   Hope this helps.

> Hello.
> Does anybody know if there is a difference between the way C# calls a COM
[quoted text clipped - 26 lines]
>
> Cheers!
Richard Blewett [DevelopMentor] - 12 Oct 2004 14:24 GMT
An apartment type mismatch is only going to be a problem if the COM marshalling code (proxy/stub) is not installed properly. This error is a COM error relating to a privileged instruction attempting to be used. It is often in relation to the proxy/stub dll (that has the interface marshalling code in it) being out of step with the definition of the interface the COM object has implemented.

Regards

Richard Blewett - DevelopMentor
http://staff.develop.com/richardb/weblog

  nntp://news.microsoft.com/microsoft.public.dotnet.languages.csharp/<Ogp4wiFsEHA.2340@TK2MSFTNGP11.phx.gbl>

Bonj,

This seems highly unlikely to me, as the mechanism in .NET ultimately
uses the same mechanism that C++ uses. Can you show how you are doing it in
.NET and how you are doing it in C++? Perhaps you are not setting up the
environment or the apartment correctly, and this could be the source of your
problems.

Hope this helps.
Bonj - 12 Oct 2004 17:33 GMT
This sounds more like it...

Are you able to provide any more information on how this problem might have
manifested itself in this scenario, and how I might go about curing it?

> An apartment type mismatch is only going to be a problem if the COM marshalling code (proxy/stub) is not installed properly. This error is a COM error relating to a privileged instruction attempting to be used. It is often in relation to the proxy/stub dll (that has the interface marshalling code in it) being out of step with the definition of the interface the COM object has implemented.
>
[quoted text clipped - 14 lines]
>  
>  Hope this helps.
Richard Blewett [DevelopMentor] - 12 Oct 2004 17:49 GMT
If you reversed engineered the typelib, you may have lost some of the marshalling information. Some IDL constructs don't make it into the typelib ([size_is] for example).You may be working from a different set of marshalling instructions than the COM object.

As Sigurd suggested, if they have't provided you with a header file use #import to import the typelib.

Regards

Richard Blewett - DevelopMentor
http://staff.develop.com/richardb/weblog

  nntp://news.microsoft.com/microsoft.public.dotnet.languages.csharp/<4A6755DD-2329-47A2-AD44-8A3E6B578C53@microsoft.com>

This sounds more like it...

Are you able to provide any more information on how this problem might have
manifested itself in this scenario, and how I might go about curing it?
Bonj - 12 Oct 2004 18:05 GMT
mmmm. I might try that again, but I definitely did that and it didn't work.

But you think that by getting the MIDL out of 'OLE/COM object viewer' from
the 'Type libraries' section and copying and pasting it into an .idl file and
then compiling that, I might have lost some information, that I possibly
wouldn't have lost by using smart pointers?

Is copying and pasting from OLE/COM object viewer's Type Libraries section
the best way to do it if I am going to go down the CoCreateInstance path?

Anyhow thanks for your help on this

> If you reversed engineered the typelib, you may have lost some of the marshalling information. Some IDL constructs don't make it into the typelib ([size_is] for example).You may be working from a different set of marshalling instructions than the COM object.
>
[quoted text clipped - 11 lines]
>  Are you able to provide any more information on how this problem might have
>  manifested itself in this scenario, and how I might go about curing it?
Bonj - 12 Oct 2004 18:09 GMT
nntp://news.microsoft.com/microsoft.public.dotnet.languages.csharp/<4A6755DD-2329-47A2-AD44-8A3E6B578C53@microsoft.com>

Is the above a link to information you think I might benefit from looking at?
If so, could you possibly copy and paste the pertinent bits into a message
and post back, because our firewall doesn't allow downloading over port 119
(nntp), we're only allowed to look at http.

Cheers
Oleg Starodumov - 13 Oct 2004 11:27 GMT
Is it possible to reproduce the problem in a simplest possible application
that only instantiates and uses this COM object and does nothing more?
(Preferrably in unmanaged C++)

Regards,
Oleg
Bonj - 13 Oct 2004 12:17 GMT
Not really, because it isn't a standard one - it's a third party custom
software, and is protected with a dongle. I have emailed the company that
produces it to ask them but whether they'll know or be able to tell me I
don't know. However I have got it fully legally installed and the dongle is
installed on my pc. The strangest thing is it works from VB.NET, VB6 and C#,
just not from any brand of C++.

The code I have been using is this:

#import "c:\program files\emblem modeller 3\MyObjx.dll"
#include <tchar.h>

int _tmain(int argc, _TCHAR* argv[])
{
    CoInitialize(NULL);
    MyObjX::_MyObjPtr model;
    HRESULT hr = model.CreateInstance(__uuidof(MyObjX::MyObj));
    if(hr == S_OK) MessageBox(NULL, _T("EMB Model successfully created"),
_T("COM test"), MB_OK); //it never is.
    CoUninitialize();
}

> Is it possible to reproduce the problem in a simplest possible application
> that only instantiates and uses this COM object and does nothing more?
> (Preferrably in unmanaged C++)
>
> Regards,
> Oleg
Sigurd Stenersen - 13 Oct 2004 12:56 GMT
> #import "c:\program files\emblem modeller 3\MyObjx.dll"
> MyObjX::_MyObjPtr model;
> HRESULT hr = model.CreateInstance(__uuidof(MyObjX::MyObj));

#import "c:\program files\emblem modeller 3\MyObjx.dll" no_namespace
_MyObjPtr model(__uuidof(MyObj));

If this doesn't work, are you sure you're using 1) the correct smart pointer
type, and 2) the correct source for uuid ?

I'd say that given the uuid source is MyObj, it would be more logical if the
smart pointer was of type IMyObjPtr.  But that is, of course, how it would
look if *I* implemented a server and used it.

Signature

Sigurd
http://utvikling.com

Bonj - 13 Oct 2004 13:23 GMT
but thanks for your efforts anyway, and I like the no_namespace thing.

> > #import "c:\program files\emblem modeller 3\MyObjx.dll"
> > MyObjX::_MyObjPtr model;
[quoted text clipped - 9 lines]
> smart pointer was of type IMyObjPtr.  But that is, of course, how it would
> look if *I* implemented a server and used it.
Bonj - 13 Oct 2004 13:23 GMT
IMyObjPtr isn't defined. _MyObjPtr is the only thing that is.
I've given up, to be honest, I've resigned myself that it's something
non-standard about the COM object. I've emailed the company to ask them and
if they don't email me back then I'm giving up.

> > #import "c:\program files\emblem modeller 3\MyObjx.dll"
> > MyObjX::_MyObjPtr model;
[quoted text clipped - 9 lines]
> smart pointer was of type IMyObjPtr.  But that is, of course, how it would
> look if *I* implemented a server and used it.
Oleg Starodumov - 13 Oct 2004 13:23 GMT
In addition to Sigurd's message...

> #import "c:\program files\emblem modeller 3\MyObjx.dll"
> #include <tchar.h>
[quoted text clipped - 8 lines]
> CoUninitialize();
> }

So you run this application and it still throws an exception
inside CreateInstance call and does not reach the next line?

Can you try with the raw CoCreateInstance, requesting only IUnknown,
so that other interfaces are not yet involved?

What threading model is used by the COM object?

Regards,
Oleg

P.S. It is better to have the smart pointer in its own scope,
otherwise (in case of successful creation of the object instance)
it will be released after CoUninitialize call, thus causing problems.

Something like this is needed:

CoInitialize()
{
  MyObjX::_MyObjectPtr model;
  ...
}
CoUninitialize()
Bonj - 13 Oct 2004 15:33 GMT
as in this..?

#import "c:\program files\emblem modeller 3\embpredictx.dll" no_namespace
#include <tchar.h>
#include <objbase.h>

int _tmain(int argc, _TCHAR* argv[])
{
CoInitialize(NULL);
IUnknown* iu;
GUID IID_EMBPredictX = {0x601EA0CD, 0xBB9B, 0x11D1,
{0x81, 0x58, 0x44, 0x45, 0x53, 0x54, 0x00, 0x00}};

GUID CLSID_EMBPredictX = {0x601EA0D0, 0xBB9B, 0x11D1,
{0x81, 0x58, 0x44, 0x45, 0x53, 0x54, 0x00, 0x00}};

HRESULT hr = CoCreateInstance(IID_EMBPredictX, NULL, CLSCTX_INPROC_SERVER,
IID_IUnknown,
    (void**)&iu);

if(hr == S_OK) MessageBox(NULL, _T("EMB Model successfully created"),
_T("COM test"), MB_OK);
CoUninitialize();
}

it does the same thing (priv. instr.), when passing the IID_EMBPredictX, and
'class not registered' when with any other combination of swapping round the
CLSID_ and the IID_ and the IID_IUnknown.

> In addition to Sigurd's message...
>
[quoted text clipped - 34 lines]
> }
> CoUninitialize()

> In addition to Sigurd's message...
>
[quoted text clipped - 34 lines]
> }
> CoUninitialize()

Rate this thread:







Free Magazines

Get these publications absolutely FREE for up to 12 months. There are no hidden fees and no obligation. Simply choose a title, complete the application form and submit it. Read more ...

Oracle MagazineNetwork ComputingComputer WorldBio-IT WorldeWeekInformation WeekInfosecurity
 
Sign In
Join
My Latest Posts
My Monitored Threads
My Blog
My Photo Gallery
My Profile
My Homepage

Start New Thread
Enable EMail Alerts
Rate this Thread



©2008 Advenet LLC   Privacy Policy - Terms of Use
This website includes both content owned or controlled by Advenet as well as content owned or controlled by third parties.