我有(遗留)VB6代码,我想从C#代码中使用.
这有点类似于这个问题,但它指的是从VB6传递一个消耗C#dll的数组.我的问题恰恰相反.
在VB中,一个dll中有一个接口,另一个中有一个实现.
接口:
[
odl,
uuid(339D3BCB-A11F-4fba-B492-FEBDBC540D6F),
version(1.0),
dual,
nonextensible,
oleautomation,
helpstring("Extended Post Interface.")
]
interface IMyInterface : IDispatch {
[id(...),helpstring("String array of errors.")]
HRESULT GetErrors([out, retval] SAFEARRAY(BSTR)* );
};
Run Code Online (Sandbox Code Playgroud)
cMyImplementationClass中的实现(片段):
Private Function IMyInterface_GetErrors() As String()
If mbCacheErrors Then
IMyInterface_GetErrors = msErrors
End If
End Function
Run Code Online (Sandbox Code Playgroud)
我用tlbimp.exe包装了这两个dll,并尝试从C#调用该函数.
public void UseFoo()
{
cMyImplementationClass foo;
...
var result = foo.GetErrors();
...
}
Run Code Online (Sandbox Code Playgroud)
调用foo.GetErrors()会导致SafeArrayRankMismatchException.我认为,这表明在安全数组一节中描述的编组问题在这里.
建议似乎是使用tlbimp.exe的/ sysarray参数或手动编辑我生成的IL,我试过.
最初的IL看起来像这样:
.method public hidebysig newslot virtual
instance string[]
marshal( safearray bstr) …Run Code Online (Sandbox Code Playgroud) 使用com-interop将用户定义的类数组从vba传递到.net(特别是c#)的正确方法是什么?
这是我的c#代码.如果我从vba调用Method1,它会因"期望的数组或用户定义类型"或"函数使用visual basic中不支持的自动化类型"而失败.
public class MyClass
{
public Method1(UserDefinedClass[] Parameters) { ... }
public Method2(Object Parameters) { ... }
}
Run Code Online (Sandbox Code Playgroud)
我已经阅读了一些关于MarshallAsAttribute类的内容.这可能是c#代码中缺少的部分吗?
这是我正在使用的vba代码:
Dim udt As New UserDefinedClass
Dim myArray()
myArray(1) = udt
myClass.Method1(myArray)
myClass.Method2(myArray)
Run Code Online (Sandbox Code Playgroud) 我需要将一个 int 或 long 数组(无关紧要)从 VB6 应用程序传递到 C# COM Visible 类。我试过像这样在 C# 中声明接口:
void Subscribe([MarshalAs(UnmanagedType.SafeArray, SafeArraySubType = VarEnum.VT_I4)]int[] notificationTypes)
void Subscribe(int[] notificationTypes)
Run Code Online (Sandbox Code Playgroud)
但他们俩都举了一个Function or interface markes as restricted, or the function uses an Automation type not supported in Visual Basic。
我应该如何声明 C# 方法?