在 C# 中访问 VB6 字符串的最快方法
我正在使用 COM 互操作。我在 VB6 中进行了一次调用,它返回大约 13000 个字符的字符串。如果我在纯 VB6 中执行调用,则执行时间大约为 800 毫秒。如果我通过 c# 和 COM Interop 执行它,大约需要 8 秒。我假设延迟是由编组引起的。
如果我对编组的看法是正确的,如果有人能建议我将其导入 C# 的最快方法,我将不胜感激。例如,这样会更好吗? a) 将其公开为字节数组 b) 向 VB6 层提供 byref 字符串参数
我也希望能提供一些示例代码。我尝试了
Marshal.PtrToStringAuto(Marshal.ReadIntPtr(myCOMObject.GetString, 0)
没有效果。
——
继弗朗西的评论之后。我只是从 C# dll 引用 VB6 dll(正在处理中)。这是 OLEView 的摘录,
interface _MyCOMObect : IDispatch {
...
[id(0x60030006)]
HRESULT GetString(
[in] _IEventHistory* p_oEventHistory,
[out, retval] _IXML** );
...
};
[
uuid(09A06762-5322-4DC1-90DD-321D4EFC9C3E),
version(1.0),
custom({17093CC6-9BD2-11CF-AA4F-304BF89C0001}, "0")
]
coclass MyCOMObject {
[default] interface _CFactory;
};
[
odl,
uuid(C6E7413F-C63A-43E4-8B67-6AEAD132F5E5),
version(1.0),
hidden,
dual,
nonextensible,
oleautomation
]
我可能应该指出参数 (p_oEventHistory) 是另一个 COM 对象,我在 C# 中实例化它,但这需要大约 80ms
S
I am using COM Interop. I have a call in VB6 which returns a string of roughly 13000 chars. If I execute the call in pure VB6 it takes about 800ms to execute. If I execute it via c# and COM Interop it takes about 8 seconds. I'm assuming the delay is caused by marshaling.
If I am correct about marshaling, I'd be grateful if someone could suggest the fastest way I can get this into C#. e.g. Would it be better to
a) expose it as a byte array
b) provide a byref string param into the VB6 layer
I would appreciate some sample code as well. I tried the
Marshal.PtrToStringAuto(Marshal.ReadIntPtr(myCOMObject.GetString, 0)
to no avail.
--
Following on from Franci's comment. I am simply referencing the VB6 dll (so in process) from a C# dll. Here's an extract from OLEView
interface _MyCOMObect : IDispatch {
...
[id(0x60030006)]
HRESULT GetString(
[in] _IEventHistory* p_oEventHistory,
[out, retval] _IXML** );
...
};
[
uuid(09A06762-5322-4DC1-90DD-321D4EFC9C3E),
version(1.0),
custom({17093CC6-9BD2-11CF-AA4F-304BF89C0001}, "0")
]
coclass MyCOMObject {
[default] interface _CFactory;
};
[
odl,
uuid(C6E7413F-C63A-43E4-8B67-6AEAD132F5E5),
version(1.0),
hidden,
dual,
nonextensible,
oleautomation
]
I should probably point out that the parameter (p_oEventHistory) is another COM object which I am instantiating in C# but that takes about 80ms
S
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(2)
有几件事: -
我的 VB6 有点生疏,但您的 IDL 摘录表明 GetString 方法实际上返回一个实现 IXML 接口的对象。我有点惊讶 Marshal.PtrToStringAuto 可以用它做任何有用的事情。您能否更改 VB6,使其实际上返回 String 类型的内容?
COM+ 的影响可能是巨大的。首先,我建议您比较第一次调用与后续调用的时间。第一次调用 COM+ 时,需要为 VB6 组件启动一个主机进程,因此第一次调用总是比较痛苦。请注意,这是在第一次调用时发生的,而不是在对象实例化时发生的。其次,在 COM+ 中配置组件的方式也会产生很大的影响;如果禁用所有实际上不需要的 COM+ 服务(例如事务),您也许能够删除 COM+ 在所有方法调用周围放置的一些拦截逻辑。最终,如果您不需要 COM+ 提供的服务,就不要使用它。
A couple of things: -
My VB6 is a little rusty, but your IDL excerpt suggests the GetString method actually returns an object that implements the IXML interface. I'm kind of surprised that Marshal.PtrToStringAuto can do anything useful with this. Could you change the VB6 so that it actually returns something of type String?
The effect of COM+ is potentially enormous. Firstly I would suggest that you compare timings for the first invocation versus subsequent invocations. COM+ will need to spin up a host process for your VB6 component the first time it's invoked so the first call is always more painful. Note this happens on first invocation, not on object instantiation. Secondly, the way your component is configured in COM+ can make a big difference too; if you disable all the COM+ services that you don't actually need (e.g. transactions) you might be able to remove some of the interception logic that COM+ places around all method invocations. Ultimately, if you don't need the services that COM+ provides, don't use it.
我会考虑使用内存映射文件或命名管道。
I would consider using memory mapped files or named pipes.