Racket COM:无法获取对象的IDispatch接口-what';下一个呢?

Racket COM:无法获取对象的IDispatch接口-what';下一个呢?,com,racket,Com,Racket,我正在尝试使用Racket 6.x中的MS UI Automation(系统下UIAutomationCore.dll的MS SDK下的UIAutomationCore.idl),安全Racket调用失败,出现无法获取IDispatch错误。代码如下: #lang racket (require ffi/com) (define clsid-cuia (string->clsid "{ff48dba4-60ef-4201-aa87-54103eef594e}")) (define cui

我正在尝试使用Racket 6.x中的MS UI Automation(系统下UIAutomationCore.dll的MS SDK下的UIAutomationCore.idl),安全Racket调用失败,出现无法获取IDispatch错误。代码如下:

#lang racket
(require ffi/com)

(define clsid-cuia (string->clsid "{ff48dba4-60ef-4201-aa87-54103eef594e}"))
(define cuia-instance (com-create-instance clsid-cuia))
(com-methods cuia-instance)

为同一接口工作的C++代码:

CoCreateInstance(CLSID_CUIAutomation, NULL,
                        CLSCTX_INPROC_SERVER, IID_IUIAutomation,
                        reinterpret_cast<void**>(ppAutomation));
CoCreateInstance(CLSID\u,空,
CLSCTX\u程序服务器,IID\u自动化,
重新解释铸造(自动化);

我的问题是,我应该怎么使用这个界面?我一直试图在球拍参考资料中找到答案,但花了很多时间没有找到答案。我还没有研究过Racket C FFI(COM的第5.12节除外),我想知道在尝试使用比上述代码更高级的代码之前是否应该学习整个FFI。

在参考资料上花了一些时间后(感谢Hans最初的评论),我现在知道了答案。这不是一个如何充分使用UIA接口的答案,而是继续的方法(正如我在问题中所问的)

由于UIAutomation等源自IUnknown,因此我们需要使用(定义COM接口…)来定义COM接口

一个开始的方法是:

(define-com-interface (_IUIAutomation _IUnknown)
  ; a better approach would be to write a macro to read the idl file,
  ; and parse it, then use the result to define the methods
  ; and define each corresponding method in order below. The first two
  ; doesn't have the full description yet
  ([CompareElements _fpointer]
  [CompareRuntimeIds _fpointer]
  [GetRootElement (_hmfun (p : (_ptr o _IUIAutomationElement-pointer))
                          -> GetRootElement p)]
  ))
由于上面的_IUIAutomationElement-pointer还没有定义,我们应该定义它以及我们将单独使用的其他接口(定义com接口…)

在将函数的返回值转换为Racket值或从Racket值转换为Racket值时,还需要注意其他细节,因此了解C FFI会有所帮助,这就是为什么在深入研究之前最好先了解Racket C FFI的原因

下面是如何使用IUnknown接口的更新。请注意,_IUIAutomation-pointer定义自动来自上面的define com接口

(define clsid-cuia (string->clsid "{ff48dba4-60ef-4201-aa87-54103eef594e}"))
(define IID_IUIAutomation (string->iid "{30cbe57d-d9d0-452a-ab13-7ac5ac4825ee}"))

(define cuia (com-create-instance clsid-cuia))
(define iuia (QueryInterface (com-object-get-iunknown cuia)
                               IID_IUIAutomation
                               _IUIAutomation-pointer))
(define root-element (GetRootElement iuia))

您应该检查COM CREATEPROCEDE命令的文档,因为函数(如C++代码中所示)需要更多的参数。特别是,您应该为接口提供IID,它可以是IDispatch IID{00020400-0000-0000-C000-0000000000 46}。最有可能的是,IID_IUIAutomation参数表示这一点。

错误是准确的,UI自动化接口源自IUnknown。大多数语言运行时只支持IDispatch接口,你在这条小溪上没有桨。但我没有说球拍是问题,我怀疑接口不是IDispatch。问题是使用这个界面最简单的方法是什么。最坏的情况下,我应该能够使用C FFI。例如,我们是否可以将(定义com接口)用于IUnknown接口?我应该补充一点,(com方法cuia实例)行用于测试com对象。我不必使用这个方法,只想使用这个接口的函数。哦,也许我应该先具体尝试一下?是和否。com create实例仅用于IUIAutomation的CLSID。但是是的,应该使用IID,只与QueryInterface命令一起使用。我将使用此添加更新答案。