问题标签 [safearray]
For questions regarding programming in ECMAScript (JavaScript/JS) and its various dialects/implementations (excluding ActionScript). Note JavaScript is NOT the same as Java! Please include all relevant tags on your question; e.g., [node.js], [jquery], [json], [reactjs], [angular], [ember.js], [vue.js], [typescript], [svelte], etc.
winapi - 如何通过 IDispatch 将 SAFEARRAY 传递给 COM 对象?
我正在尝试调用 COM 对象的方法,其中记录的参数之一是“字节数组”。实际声明取决于您正在查看的每种语言的文档:
在C#语言中:
/li>C++语言;
/li>VB语言:
/li>在F#语言中:
/li>
我正在使用的对象也可以使用COM访问。该对象提供了一个早期绑定接口 ,ICryptoTransform
该接口将方法声明为 using SAFEARRAY
。
从类型库:
使用IDL语法
/li>使用对象 Pascal语法:
/li>
这意味着在使用早期绑定时,您必须传递方法 a SAFEARRAY
。我使用的语言支持 SafeArray API,我是否可以轻松地执行调用:
这是类似 java 语言的相同代码:
一切正常;但这不是我的问题。
注意:我试图强调这是一个与语言无关的问题,因为COM 是一种与语言无关的技术。但是在某些时候,我们必须实际使用一种语言来演示代码。有些人将语言与技术混淆了。如果我知道 Knuth 发明的语言,我会使用它。
但是后期绑定IDispatch
呢?
现在我们知道我们可以将 a 传递SAFEARRAY
给 COM 对象(使用early-binding时),我需要解决使用late-binding传递数组的问题。
注意:除此之外,如何通过 IDispatch 将 SAFEARRAY 传递给 COM 对象的问题对我很有用
ICryptoTransform
。
IDispatch
一些语言提供了在运行时通过接口调用方法的自动机制(即后期绑定)。事实上IDispatch
,后期绑定是为 VBScript 发明的:
.NET 4.0 中添加了后期绑定编译器自动魔法:
Delphi 中也存在后期绑定编译器魔法:
我碰巧在使用 Dephi,这个调用失败了。
但这并不是真正的编译器魔法
VBScript、C# dynamic 和 Delphi 所做的并不是什么神奇的事情。他们只是在打电话IDispatch.Invoke
:
混乱正在设置这些参数:
真正的技巧是dispParams
包含参数的结构。
参数将是一个变体
通过 DISPARAMS 传递的参数都是变体:
所以无论发生什么,我的“字节数组”都将是一个变体。
A VARIANT
,在 Win32 中,只是一个联合,它包含:
VARTYPE vt
:联合中的数据类型。适当的工会成员,例如:
/li>
到目前为止,我一直在传递一种类型的变体:
MSDN 记录了当您想使用parray union时必须执行的操作VT_ARRAY | *
:
价值:
VT_ARRAY | <anything>
说明:传递了一个数据类型的数组。VT_EMPTY 和 VT_NULL 是与 VT_ARRAY 组合的无效类型。pbyrefVal中的指针指向一个数组描述符,它描述了数组的维度、大小和内存中的位置。
这意味着使用该parray
成员:
您需要将parray
member 设置为指向SAFEARRAY
结构的指针:
就我而言,我的字节数组实际上是 a SAFEARRAY
,然后将其存储在一个变体中:
注意:当然我还没有疯狂到自己创建了这个安全数组;我正在使用
SafeArrayCreate
api 功能。我只是在证明这一切都是可知的,而不是魔法。
换句话说,我传递了一个字节的数组变体
换句话说,我正在传递一个字节数组,包装在一个变体中,因为所有调用:
一定是。除了后期绑定调用抛出错误:
那么我可能做错了什么?
如何将一个字节数组传递给后期绑定 IDispatch
调用?
我的问题
如何通过 IDispatch 将 SAFEARRAY 传递给 COM 对象?
delphi - delphi7中使用PSafeArray调用COM时出错
我有一个需要使用 COM 调用的过程,它在 C# 中声明如下:
导入的 TypeLibrary 中的 Delphi 声明为:
我有这段代码可以将整数数组转换为 PSafeArray:
这段代码调用我的 COM 函数
但错误发生:
“ EOLeExeption 带有消息 'SafeArray of rank 0 已被传递给期望 rank 1 数组的方法' ...”
我应该怎么做?
c# - 将 IUnknowns 的 SAFEARRAY 转换/转换为接口指针的可迭代数组
我在 C# 中有以下接口,其中一个具有相同名称(没有我)的类实现它。
公共类 Order 的实现: IOrder 只是三个私有字段和一个带有所需 3 个参数的构造函数。
在其他地方,我有以下方法,其结果是我想在 C++ 非托管代码中工作,通过 COM 和 .tlb/.tlh 文件传输到那里。
我已经设法使用 C# 托管代码在 C++ 非托管代码之间进行基础工作。
但是类数组被证明是一个不同的挑战......
我承认,对我来说,COM 是新的,令人困惑,C++ 早已被遗忘......,但我正在开发这两个库,所以我不会放弃;我希望 C++ DLL 在某些程序和我的 C# 代码之间充当代理。
澄清:我既没有使用 MFC 也没有使用 ATL。我在 C++ 代码中使用#import 来获取 C# 生成的接口和类指针以及其他我不太了解的 COM 内容。
经过一个小时的研究,我只是去这里寻求帮助>.<
以下是我想要实现的 C++ 代码。
现在,我需要一些我还不明白的 COM 魔法来将 SAFEARRAY* 转换为 IOrderPtr* 或其他东西,这样我就可以遍历返回的整个数组并调用“Order”类型的方法
- 获取数量()
- 获取订单类型()
- 获取位置类型()
因此,对于第一个周期,我将获得值 1、2、3,对于第二个周期,我将获得值 4、5、6。
因为我是 C++ 和 C# 库的作者,所以我可以跳过所有这些 COM 疯狂的东西,并制作方法来获取集合计数和其他方法来获取特定索引上的属性值。
但这似乎并不好。我怀疑我想要的机制很简单,但我在谷歌上找到的所有答案总是缺少一些东西。
c# - 尝试获取类方法指针时的 E_NOINTERFACE
我正在从 C++ 非托管代码中调用 C# 方法。我从数组中返回的类实例中获取值时遇到问题。
我已经稍微简化了代码
这是有问题的方法。
这是 IScOrder 接口
这是 ScOrder 的实现
这是 C++ 代码,在我之前的请求中得到 Zdeslav Vojkovic 的帮助后。问题在评论中描述
- 我没有使用 ATL 或 MFC。
- C++ tlb 文件是通过 regasm 生成的。
COM 初始化和调用 GetOrders 方法效果很好
感谢 Zdeslav,我发现我可以在 order(punk) 中进行调试:
所以我走进秩序(朋克)看看那里发生了什么。我进入了一个“comip.h”
...然后我进入了 _QueryInterface(p) 实现,也在 comip.h
现在这里的问题是返回的“hr”的值是 E_NOINTERFACE ...这是不对的。
我不是 C++ 或 COM 专家...请帮助 :)
.net - 是否可以在 SAFEARRAY 中编组 ref 参数
这是我的 C# 服务器方法:
我的 C++ 客户端正在设置并调用此方法。这工作正常,但状态和输出变量似乎没有链接。就好像它们是按值而不是按引用传递的。
这是我的客户代码:
有人可以在设置 SAFEARRAY 参数方面提供帮助,以便将“ref”参数复制回来吗?
c++ - 如何遍历 SAFEARRAY **
如何遍历 C++ 安全数组指针指向指针并访问其元素。
我试图复制 Lim Bio Liong http://social.msdn.microsoft.com/Forums/en-US/vcgeneral/thread/022dba14-9abf-4872-9f43-f4fc05bd2602发布的解决方案, 但最奇怪的是 IDL方法签名出来是
代替
有任何想法吗?
提前致谢
c# - 通过 COM Interop 编组托管结构的 SAFEARRAY
我正在尝试将从 ac# 库导出的结构数组传递给 c++ 代码。目标是将结构的 SAFEARRAY 从 c++ 传递到 c#。
我已按照指示
但是通过调用 GetRecordInfoFromTypeInfo 得到这个错误
0x80028019 旧格式或无效类型库。
c++ - 如何将 fstream 读入 LPSAFEARRAY?
我正在尝试在 C++ 中调用托管 dll 上的方法。其中一个参数是字节数组,库导入将其转换为 LPSAFEARRAY。字节数组/LPSAFEARRAY 旨在成为文件的内容。如何将文件读入 LPSAFEARRAY 以传递给方法?
这是生成的库头文件中的函数签名:
第二个参数是另一个字节数组,当它从方法返回时我需要使用它。
c# - 如何从多维 PSafeArray 中获取数据?
我需要从PSafeArray
Delphi 中读取数据。
这PSafeArray
是由用 C# 开发的 DLL 中实现的方法返回的。此方法返回一个二维字符串数组string[,]
。如何PSafeArray
在 Delphi 中读取这样的结果?
vb.net - 返回 SAFEARRAY(Long) 导致 SafeArrayTypeMismatchException 的 COM 对象
我使用他们提供的 API 类型库为我们在工作中使用的程序编写插件。它是一个名为 SCAPI 的 COM 对象。COM 对象是为 VB6 编写的,因此当我为 .NET 添加它的引用时,会创建它的互操作版本。
当我使用以下代码时,它应该根据文档返回一个 SAFEARRAY(Long),我收到一条错误消息,说我有一个 SafeArrayTypeMismatchException。
该错误是从 SCAPI.PropertyBagClass.get_Value(Object Property) 函数引发的,该函数是 COM 对象的一部分,而不是我写的东西。经过我所做的所有研究,我似乎无法弄清楚我需要做什么才能使其正常工作。我使用 tlbimp.exe 来获取方法信息,但它似乎不包含任何 [out] 标签,即使我使用了相同的函数 oBag.Value("Name"),它返回一个字符串值并且不会抛出错误: