.NET COM/ActiveX problem

  • Thread starter Thread starter Steven
  • Start date Start date
S

Steven

I've followed some websites advice for creating an "ActiveX assembly" and
everything was going along fine until I ran into a problem. The
methods/properties aren't marshalling correctly. I have an interface:

[ComVisible(true), Guid("B3A60DA4-8F40-4336-87D6-66282A702AAC"),
InterfaceType(ComInterfaceType.InterfaceIsIDispatch)]
public interface IMyHostWnd
{
[DispId(1)]
VIEWSTATE MyState { get; set; }
[DispId(2)]
int MyCount { get; }
[DispId(3)]
bool GetMyType(int Index, ref Nullable<MY_TYPE> MyType);
[DispId(4)]
bool AddMyWindow(MY_TYPE MyType);
}

Then the impl:

[Guid("B3A60DA6-8F40-4336-87D6-66282A702AAC")]
[ComSourceInterfaces(typeof(IMyHostWndEvents))]
[ProgId("MyHost.MyHostWnd")]
public partial class MyHostWnd : UserControl, IMyHostWnd
{
[ComVisible(true)]
[DispId(4)]
public bool AddMyWindow(MY_TYPE MyType)
{
...
}

....
}

The struct passed in is defined as:

[ComVisible(true)]
//[MarshalAs(UnmanagedType.SafeArray)]
public struct MY_TYPE
{
[MarshalAs(UnmanagedType.LPStruct)]
public Guid Identifier;
public string Manufacturer;
public string Model;
[MarshalAs(UnmanagedType.LPStruct)]
public Guid MyMethod;
}

The problem is when I use it in my unmanaged app I get all sorts of
marshalling errors, like the methods aren't lining up correctly. One time
I'll get "invalid number of parameters", I'll tweak my DispIDs or move some
methods around, recompile and it'll say "member not found", or some other
error telling me they aren't lined up correctly. I look at the object in
the OLE-COM Object viewer, and everything seems to be laid out correctly as
it looks in my .NET assembly.

On my unmanaged/MFC side I'm doing this:

//.h
CWnd m_MyWnd;

//cpp - error checking removed for post simplicity
BOOL b = m_MyWnd.CreateControl(MyHost::CLSID_IMyHostWnd, NULL,
WS_TABSTOP|WS_VISIBLE, rect, this, WM_USER+1);

LPUNKNOWN pUnk = m_MyWnd.GetControlUnknown();
pUnk->QuerryInterface(MyHost::IID__MyHostWnd, (LPVOID*)&m_pIMyHost);
MyHost::MY_TYPE mt;
//populate mt then...
m_pIMyHost->AddMyWindow(mt); //gets scrambled on this func, thows
_com_error


It never makes it to the AddMyWindow impl., I can step in until the
_com_dispatch_method() where I can see the dipatch id matched my impl and
interface.

Thanks for any help/advise.

Steven
 
I added a test method that just showed a messagebox and took no params, and
it worked fine. So it has to do with my passing the struct in as a param.
Any thoughts?
 
Really confused. I removed the structure all together and passed the values
in as individual values and it still gives me "The Parameter is incorrect".

It's being imported this way:

//c++
VARIANT_BOOL IMyHostWnd::AddMyWindow ( GUID Identifier, _bstr_t
Manufacturer, _bstr_t Model, GUID MyMethod )

//c#
[DispId(4)]
bool AddMyWindow(Guid Identifier, string Manufacturer, string Model, Guid
MyMethod);

If I do no params, everything works, what gives?



Steven said:
I added a test method that just showed a messagebox and took no params, and
it worked fine. So it has to do with my passing the struct in as a param.
Any thoughts?

Steven said:
I've followed some websites advice for creating an "ActiveX assembly" and
everything was going along fine until I ran into a problem. The
methods/properties aren't marshalling correctly. I have an interface:

[ComVisible(true), Guid("B3A60DA4-8F40-4336-87D6-66282A702AAC"),
InterfaceType(ComInterfaceType.InterfaceIsIDispatch)]
public interface IMyHostWnd
{
[DispId(1)]
VIEWSTATE MyState { get; set; }
[DispId(2)]
int MyCount { get; }
[DispId(3)]
bool GetMyType(int Index, ref Nullable<MY_TYPE> MyType);
[DispId(4)]
bool AddMyWindow(MY_TYPE MyType);
}

Then the impl:

[Guid("B3A60DA6-8F40-4336-87D6-66282A702AAC")]
[ComSourceInterfaces(typeof(IMyHostWndEvents))]
[ProgId("MyHost.MyHostWnd")]
public partial class MyHostWnd : UserControl, IMyHostWnd
{
[ComVisible(true)]
[DispId(4)]
public bool AddMyWindow(MY_TYPE MyType)
{
...
}

....
}

The struct passed in is defined as:

[ComVisible(true)]
//[MarshalAs(UnmanagedType.SafeArray)]
public struct MY_TYPE
{
[MarshalAs(UnmanagedType.LPStruct)]
public Guid Identifier;
public string Manufacturer;
public string Model;
[MarshalAs(UnmanagedType.LPStruct)]
public Guid MyMethod;
}

The problem is when I use it in my unmanaged app I get all sorts of
marshalling errors, like the methods aren't lining up correctly. One
time I'll get "invalid number of parameters", I'll tweak my DispIDs or
move some methods around, recompile and it'll say "member not found", or
some other error telling me they aren't lined up correctly. I look at
the object in the OLE-COM Object viewer, and everything seems to be laid
out correctly as it looks in my .NET assembly.

On my unmanaged/MFC side I'm doing this:

//.h
CWnd m_MyWnd;

//cpp - error checking removed for post simplicity
BOOL b = m_MyWnd.CreateControl(MyHost::CLSID_IMyHostWnd, NULL,
WS_TABSTOP|WS_VISIBLE, rect, this, WM_USER+1);

LPUNKNOWN pUnk = m_MyWnd.GetControlUnknown();
pUnk->QuerryInterface(MyHost::IID__MyHostWnd, (LPVOID*)&m_pIMyHost);
MyHost::MY_TYPE mt;
//populate mt then...
m_pIMyHost->AddMyWindow(mt); //gets scrambled on this func, thows
_com_error


It never makes it to the AddMyWindow impl., I can step in until the
_com_dispatch_method() where I can see the dipatch id matched my impl and
interface.

Thanks for any help/advise.

Steven
 
Seems it had to do with the GUIDs. I still don't know what the problem was,
but I changed it to string GUIDs and converted it to Guids on the impl side
and it worked. I'd still be interested in knowing what the solution is to
this.


Steven said:
Really confused. I removed the structure all together and passed the
values in as individual values and it still gives me "The Parameter is
incorrect".

It's being imported this way:

//c++
VARIANT_BOOL IMyHostWnd::AddMyWindow ( GUID Identifier, _bstr_t
Manufacturer, _bstr_t Model, GUID MyMethod )

//c#
[DispId(4)]
bool AddMyWindow(Guid Identifier, string Manufacturer, string Model, Guid
MyMethod);

If I do no params, everything works, what gives?



Steven said:
I added a test method that just showed a messagebox and took no params,
and it worked fine. So it has to do with my passing the struct in as a
param. Any thoughts?

Steven said:
I've followed some websites advice for creating an "ActiveX assembly"
and everything was going along fine until I ran into a problem. The
methods/properties aren't marshalling correctly. I have an interface:

[ComVisible(true), Guid("B3A60DA4-8F40-4336-87D6-66282A702AAC"),
InterfaceType(ComInterfaceType.InterfaceIsIDispatch)]
public interface IMyHostWnd
{
[DispId(1)]
VIEWSTATE MyState { get; set; }
[DispId(2)]
int MyCount { get; }
[DispId(3)]
bool GetMyType(int Index, ref Nullable<MY_TYPE> MyType);
[DispId(4)]
bool AddMyWindow(MY_TYPE MyType);
}

Then the impl:

[Guid("B3A60DA6-8F40-4336-87D6-66282A702AAC")]
[ComSourceInterfaces(typeof(IMyHostWndEvents))]
[ProgId("MyHost.MyHostWnd")]
public partial class MyHostWnd : UserControl, IMyHostWnd
{
[ComVisible(true)]
[DispId(4)]
public bool AddMyWindow(MY_TYPE MyType)
{
...
}

....
}

The struct passed in is defined as:

[ComVisible(true)]
//[MarshalAs(UnmanagedType.SafeArray)]
public struct MY_TYPE
{
[MarshalAs(UnmanagedType.LPStruct)]
public Guid Identifier;
public string Manufacturer;
public string Model;
[MarshalAs(UnmanagedType.LPStruct)]
public Guid MyMethod;
}

The problem is when I use it in my unmanaged app I get all sorts of
marshalling errors, like the methods aren't lining up correctly. One
time I'll get "invalid number of parameters", I'll tweak my DispIDs or
move some methods around, recompile and it'll say "member not found", or
some other error telling me they aren't lined up correctly. I look at
the object in the OLE-COM Object viewer, and everything seems to be laid
out correctly as it looks in my .NET assembly.

On my unmanaged/MFC side I'm doing this:

//.h
CWnd m_MyWnd;

//cpp - error checking removed for post simplicity
BOOL b = m_MyWnd.CreateControl(MyHost::CLSID_IMyHostWnd, NULL,
WS_TABSTOP|WS_VISIBLE, rect, this, WM_USER+1);

LPUNKNOWN pUnk = m_MyWnd.GetControlUnknown();
pUnk->QuerryInterface(MyHost::IID__MyHostWnd, (LPVOID*)&m_pIMyHost);
MyHost::MY_TYPE mt;
//populate mt then...
m_pIMyHost->AddMyWindow(mt); //gets scrambled on this func, thows
_com_error


It never makes it to the AddMyWindow impl., I can step in until the
_com_dispatch_method() where I can see the dipatch id matched my impl
and interface.

Thanks for any help/advise.

Steven
 
Back
Top