我有(遗留)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) 我正在尝试提高复杂数据库读取操作的性能.我发现一些代码在有限的测试中比以前尝试使用各种技术(包括手动调整的存储过程)执行得更快.它正在使用Dapper,但Dapper并不是主要关注点.
public IEnumerable<Order> GetOpenOrders(Guid vendorId)
{
var tasks = GetAllOrders(vendorId)
.Where(order => !order.IsCancelled)
.Select(async order => await GetLineItems(order))
.Select(async order =>
{
var result = (await order);
return result.GetBalance() > 0M ? result : null;
})
.Select(async order => await PopulateName(await order))
.Select(async order => await PopulateAddress(await order))
.ToList();
Task.WaitAll(tasks.ToArray<Task>());
return tasks.Select(t => t.Result);
}
private IDbConnection CreateConnection()
{
return new SqlConnection("...");
}
private IEnumerable<Order> GetAllOrders(Guid vendorId)
{
using (var db = CreateConnection())
{
return db.Query<Order>("...");
}
}
private async …Run Code Online (Sandbox Code Playgroud)