看起来这似乎是一个在这里很容易找到的问题,但如果此前已经有人问过,那我就没看到在哪里。
基本上,我是一名.NET开发人员,必须暂时使用VB6并学习制作COM DLL。我正在使用C#进行工作,尝试使用该语言创建的COM DLL向一些VB6代码返回自定义类/结构,并且虽然这里的答案在从COM方法返回string
或int
时足够简单易用,但我在实际对象中遇到了麻烦。
示例代码:
C#
using System;
using System.Runtime.InteropServices;
namespace One.Two.Three
{
[Guid("<some GUID>"), ClassInterface(ClassInterfaceType.None)]
public class SomeClass : ISomeClass
{
public string Test1 { get; set; } = "Tesuto Ichiban";
public string Test2 { get; set; } = "Tesuto Niban";
public SomeClass SomeFunction(ref string str1, ref string str2, ref string str3,
ref bool someBool, string str4)
{
return new SomeClass();
}
}
[Guid("<another GUID>")]
public interface ISomeClass
{
SomeClass SomeFunction(ref string str1, ref string str2, ref string str3, ref bool
someBool, string str4);
}
public class Test
{
public string Test1 { get; set; } = "Tesuto Ichiban";
public string Test2 { get; set; } = "Tesuto Niban";
}
}
VB6
MsgBox ("start")
Dim result As Object
Dim someObj
Set someObj = CreateObject("One.Two.Three.SomeClass")
result = CallByName(someObj, "SomeFunction", VbMethod, "1", "2", "3", True, "4")
MsgBox (result)
'MsgBox (result.toString())
'MsgBox (result.Test1)
'MsgBox (result.Test2)
MsgBox ("end")
当返回值是string
或int
且result
被声明为String
时,此方法非常适用,并且该值可以传递到MsgBox
并正常显示给用户。但是,如果返回SomeClass
或Test
中的任何一个,则尝试将result.[toString()/Test1/Test2]
传递给MsgBox
会导致消息“start”和“end”仍然正常显示给用户,但在其中没有任何内容显示(甚至没有空白消息)。
值得注意的是,通过返回Test
的实例并保留result
声明为String
,对MsgBox(result)
的调用将显示“One.Two.Three.Test”,这表明那里正在发生一些事情。
那么......问题是:
还需要做什么才能使该对象相对于VB6应用程序更加易于访问?
特别是,我将需要返回一个数组,List<T>
或某些具有多个成员的对象。再次,这似乎是应该在Google或SO上相对容易找到的东西,但它似乎被其他搜索结果淹没了。
P.S.该dll的.NET Framework为4.5。(我使用了4.0文件夹中的RegAsm,而不是链接答案中特别提到的2.0)。如果需要将其降至4.0,那么我可能可以做到,但可能无法完全降至2.0。
CallByName
时添加Set
关键字似乎对我的情况最重要。 - Panzercrisis