COM interop and Object Required

P

pblackburn

Summary
Getting the error message Run time error 424 Object Required when attempting
to assign a value to a C# COM visible property of type object.

I have created a COM visible class as below

using System;
using System.Collections.Generic;
using System.Text;
using System.Runtime.InteropServices;

namespace ComObjectTest
{
[InterfaceType(ComInterfaceType.InterfaceIsDual)]
[Guid("6350DE7F-8F6E-4623-88B1-C218CB557BBB")]
public interface IComInterface
{
string String {get;set;}
int Long {get;set;}
DateTime Date {get;set;}
Object Value {get;set;}
}


[Guid("42653F00-FD97-4a8d-AF1B-9CB81842C922")]
[ClassInterface(ClassInterfaceType.None),Serializable]
public class ComObject : IComInterface
{

Object m_Value = null;
string m_String = string.Empty;
int m_Integer = 0;
DateTime m_Date = new DateTime();

public ComObject()
{
}

#region IComInterface Members

public Object Value
{
get {return m_Value;}
set {m_Value = value;}
}

public string String
{
get {return m_String;}
set { m_String = value;}
}

public int Long
{
get { return m_Integer; }
set { m_Integer = value;}
}

public DateTime Date
{
get { return m_Date; }
set { m_Date = value; }
}

}
#endregion
}

In VB6 I have added a reference to this class.
The class is displayed as expected in the VB6 object viewer

I have the following VB6 code

Dim o As ComObject

Set o = New ComObject

o.Date = Now()
o.Long = 100
o.String = "Hello World"
o.Value = 123

The final line causes the Object expected error.

Could someone please explain where I am going wrong?

Many thanks
 
A

Anthony Jones

pblackburn said:
Summary
Getting the error message Run time error 424 Object Required when attempting
to assign a value to a C# COM visible property of type object.

I have created a COM visible class as below

using System;
using System.Collections.Generic;
using System.Text;
using System.Runtime.InteropServices;

namespace ComObjectTest
{
[InterfaceType(ComInterfaceType.InterfaceIsDual)]
[Guid("6350DE7F-8F6E-4623-88B1-C218CB557BBB")]
public interface IComInterface
{
string String {get;set;}
int Long {get;set;}
DateTime Date {get;set;}
Object Value {get;set;}
}


[Guid("42653F00-FD97-4a8d-AF1B-9CB81842C922")]
[ClassInterface(ClassInterfaceType.None),Serializable]
public class ComObject : IComInterface
{

Object m_Value = null;
string m_String = string.Empty;
int m_Integer = 0;
DateTime m_Date = new DateTime();

public ComObject()
{
}

#region IComInterface Members

public Object Value
{
get {return m_Value;}
set {m_Value = value;}
}

public string String
{
get {return m_String;}
set { m_String = value;}
}

public int Long
{
get { return m_Integer; }
set { m_Integer = value;}
}

public DateTime Date
{
get { return m_Date; }
set { m_Date = value; }
}

}
#endregion
}

In VB6 I have added a reference to this class.
The class is displayed as expected in the VB6 object viewer

I have the following VB6 code

Dim o As ComObject

Set o = New ComObject

o.Date = Now()
o.Long = 100
o.String = "Hello World"
o.Value = 123

The final line causes the Object expected error.

Could someone please explain where I am going wrong?


You have the Value property defined as:-

Object Value {get;set;}


on the interface.

Hence VB6 would expect you to use:-

Set o.Value = <some expression the results in an object reference>

C# will cause a value type such as an int to be boxed as a reference type
when assigned to a variable that has the Object type. VB6 doesn't do that
hence attempting to assign an int to an interface member that is expecting
an object will fail.
 
P

pblackburn

Anthony Jones said:
pblackburn said:
Summary
Getting the error message Run time error 424 Object Required when attempting
to assign a value to a C# COM visible property of type object.

I have created a COM visible class as below

using System;
using System.Collections.Generic;
using System.Text;
using System.Runtime.InteropServices;

namespace ComObjectTest
{
[InterfaceType(ComInterfaceType.InterfaceIsDual)]
[Guid("6350DE7F-8F6E-4623-88B1-C218CB557BBB")]
public interface IComInterface
{
string String {get;set;}
int Long {get;set;}
DateTime Date {get;set;}
Object Value {get;set;}
}


[Guid("42653F00-FD97-4a8d-AF1B-9CB81842C922")]
[ClassInterface(ClassInterfaceType.None),Serializable]
public class ComObject : IComInterface
{

Object m_Value = null;
string m_String = string.Empty;
int m_Integer = 0;
DateTime m_Date = new DateTime();

public ComObject()
{
}

#region IComInterface Members

public Object Value
{
get {return m_Value;}
set {m_Value = value;}
}

public string String
{
get {return m_String;}
set { m_String = value;}
}

public int Long
{
get { return m_Integer; }
set { m_Integer = value;}
}

public DateTime Date
{
get { return m_Date; }
set { m_Date = value; }
}

}
#endregion
}

In VB6 I have added a reference to this class.
The class is displayed as expected in the VB6 object viewer

I have the following VB6 code

Dim o As ComObject

Set o = New ComObject

o.Date = Now()
o.Long = 100
o.String = "Hello World"
o.Value = 123

The final line causes the Object expected error.

Could someone please explain where I am going wrong?


You have the Value property defined as:-

Object Value {get;set;}


on the interface.

Hence VB6 would expect you to use:-

Set o.Value = <some expression the results in an object reference>

C# will cause a value type such as an int to be boxed as a reference type
when assigned to a variable that has the Object type. VB6 doesn't do that
hence attempting to assign an int to an interface member that is expecting
an object will fail.
Thanks
I think the fact that the COM object browser in VB had this property of type
Variant lead me to believe I could simply assign a value. I can Set the
Value to anopther object as you suggested using the SET o.Value = ? method.
So my next question is how do I expose a C# property to VB as a VARIANT?

Thanks again
 
J

Jialiang Ge [MSFT]

Good morning pblackburn. Welcome to Microsoft Newsgroup support service. My
name is Jialiang Ge [MSFT]. It's my pleasure to work with you on this issue.

The symptom you found is caused by a known code defect of Microsoft's
tlbexp. Let's first look at the resolution of the issue, then I will
explain the background information and "WHY" in detail.

**RESOLUTION**
We need to use late binding to set value for the Object property "Value".

Dim obj As Object
Set obj = New ComObject
obj.Value = 123

(Note: obj is declared as Object due for "late binding")

**CAUSE**
Looking at the type library of the .NET component with oleview.exe, you
will find that the Value property is defined in this way:

interface IComInterface : IDispatch {
[id(00000000), propget]
HRESULT Value([out, retval] VARIANT* pRetVal);
[id(00000000), propputref]
HRESULT Value([in] VARIANT pRetVal);
};

The value is exposed as "VARIANT", instead of an Object. (This can answer
your follow up question for Anthony Jones), however, why can't we use it as
a normal VARIANT in VB6 to set an integer? It's because of the setting
"propputref". "propputref" only allows the value to be a reference type. We
need to pass value types instead (specifically an int, string or decimal
value) which doesn't work because the setter is marked as a 'propputref'.
An expected setting is "propput". Microsoft has admitted this code defect
when our tool generates the tlb. The workaround is to use "late binding",
instead of "early binding", as is demonstrated in the "RESOLUTION" part of
my message. Pblackburn, please have a try and let me know whether it works
for you. If you have any other concerns or questions, please DON'T hesitate
to tell me.

Regards,
Jialiang Ge ([email protected], remove 'online.')
Microsoft Online Community Support

Delighting our customers is our #1 priority. We welcome your comments and
suggestions about how we can improve the support we provide to you. Please
feel free to let my manager know what you think of the level of service
provided. You can send feedback directly to my manager at:
(e-mail address removed).

==================================================
Get notification to my posts through email? Please refer to
http://msdn.microsoft.com/subscriptions/managednewsgroups/default.aspx#notif
ications.

Note: The MSDN Managed Newsgroup support offering is for non-urgent issues
where an initial response from the community or a Microsoft Support
Engineer within 1 business day is acceptable. Please note that each follow
up response may take approximately 2 business days as the support
professional working with you may need further investigation to reach the
most efficient resolution. The offering is not appropriate for situations
that require urgent, real-time or phone-based interactions or complex
project analysis and dump analysis issues. Issues of this nature are best
handled working with a dedicated Microsoft Support Engineer by contacting
Microsoft Customer Support Services (CSS) at
http://msdn.microsoft.com/subscriptions/support/default.aspx.
==================================================
This posting is provided "AS IS" with no warranties, and confers no rights.
 
J

Jialiang Ge [MSFT]

Hello pblackburn,

I am writing to check the status of the issue on your side. Would you mind
letting me know the result of my workarounds? If you need further
assistance, feel free to let me know. I will be more than happy to be of
assistance.

Have a great day!

Regards,
Jialiang Ge ([email protected], remove 'online.')
Microsoft Online Community Support

=================================================
Delighting our customers is our #1 priority. We welcome your comments and
suggestions about how we can improve the support we provide to you. Please
feel free to let my manager know what you think of the level of service
provided. You can send feedback directly to my manager at:
(e-mail address removed).

This posting is provided "AS IS" with no warranties, and confers no rights.
=================================================
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Top