使用com互操作从VBA调用C#dll时出现类型不匹配错误

使用com互操作从VBA调用C#dll时出现类型不匹配错误,c#,.net,ms-access,vba,com-interop,C#,.net,Ms Access,Vba,Com Interop,使用COM互操作从VBA代码调用C#方法时,参数有哪些限制 我发现,如果我调用一个采用单一简单类型(字符串、int等)的方法,它就可以工作,但是调用一个采用自定义类作为参数的方法会失败——编译VBA代码时会出现“类型不匹配”错误 C#代码: VBA代码: Dim service As New foo.Service service.setString("this works") Dim complexClass as New foo.XXX Rem This fails with a ty

使用COM互操作从VBA代码调用C#方法时,参数有哪些限制

我发现,如果我调用一个采用单一简单类型(字符串、int等)的方法,它就可以工作,但是调用一个采用自定义类作为参数的方法会失败——编译VBA代码时会出现“类型不匹配”错误

C#代码:

VBA代码:

Dim service As New foo.Service
service.setString("this works")

Dim complexClass as New foo.XXX 

Rem This fails with a type mismatch error
service.setXXX(complexClass)
如上所述,VBA编译器在这一行阻塞:service.setXXX(complexClass)


有什么想法吗?

示例代码中setString和setXXX的方法签名不完整,因为它没有说明是返回void还是任何其他数据类型。 如果setXXX返回void,请尝试删除VBA方法调用中参数周围的括号,如:

service.setXXX complexClass
说明:

在VBA中,不应将sub rotine的参数括在括号中。可以很容易地验证这一点:创建一个具有两个参数的子程序,并尝试调用它(将参数包装在括号中):

//C#
public void setXXX2(XXX val, XXX val2) { }

回到您的示例,当您将单个参数包装在括号内时,您创建了一个,在本例中,它的计算结果是一个简单的数据值,类型为String

您可以看到,为了进行测试,您自己在类中添加了一个新方法(我称之为GetParameterType):

public class Service { 
    public void setString(String val) {  }
    public void setXXX(XXX val) { }
    public void setXXX2(XXX val, XXX val2) { }

    public string GetParameterType(object val) {
        return val.GetType().Name;
    }
} 
然后运行方法,直接传递变量,然后传递括号中的变量

MsgBox service.GetParameterType(complexClass) ' Returns XXX
MsgBox service.GetParameterType((complexClass)) ' Returns String

很抱歉没有发布答案。相反,我有一个建议:如果您打算进行大量的COM互操作(无论是使用COM对象的r.NET,还是通过COM可调用包装器访问.NET对象的COM对象,请购买这本书:如果书中没有,您不需要知道它。XXX实现了任何接口吗?+1,围绕方法参数添加偏执是不正确的。它甚至可以更改ByRe方法调用的语义f到a ByVal调用:谢谢,这真的很有帮助。不过有一个问题,如果我从VB代码中传递一个数组,你的GetParameterType实现似乎不起作用。COR_E_SAFEARRAYTYPEMISMATCH失败了。我尝试创建了一个类似的方法,以object[]为参数,结果相同。有什么想法吗?
public class Service { 
    public void setString(String val) {  }
    public void setXXX(XXX val) { }
    public void setXXX2(XXX val, XXX val2) { }

    public string GetParameterType(object val) {
        return val.GetType().Name;
    }
} 
MsgBox service.GetParameterType(complexClass) ' Returns XXX
MsgBox service.GetParameterType((complexClass)) ' Returns String