编辑 :
我有一个 ATL 简单对象 MyATLObject,只有一种方法:
STDMETHODIMP CMyATLObject::EVAL( DOUBLE* x, long AddressOfFunc )
{
*x = toto<FCTPTR>(*((FCTPTR) AddressOfFunc)) ;
return S_OK;
}
其中 toto 是由定义的模板函数
#pragma once
template<typename F>
double toto( F f )
{
return f(0.0) ;
}
其中 FCTPTR 定义为
typedef double (__stdcall * FCTPTR)( double );
我的 ATL 方法使用 double x 来存储 toto 的结果,而 long AddressOfFunc 是 VBA 函数的 AddressOf。
这通过地址将 VBA 函数传递给 ATL 方法。这太可怕了。否则,它如何能够做同样的事情——将 VBA 函数传递给 ATL 方法,例如通过在 ATL 端定义一个接口?
非常感谢。
///////////////////////////////////////// ///////////////////////////////////////// ///////////////////////////////////////// ////////////////////////////
我的问题的第一个版本:
我实际上是在做以下事情:创建一个 ATL/COM 项目,向其中添加一个名为 MyATLObject 的“简单 ATL 对象”:
1)在idl文件中:
interface IMyATLObject : IDispatch{
[id(1), helpstring("method EVAL")] HRESULT EVAL(DOUBLE* x, long AddressOfFunc) ;
};
2 在 MyATLObject.h 文件中:
一个
#include "MyStupidEvaluator.h"
和一个
typedef double (__stdcall * FCTPTR)( double );
课外,课内
public:
STDMETHOD(EVAL)(DOUBLE* x, long AddressOfFunc) ;
最后在 MyATLObject.cpp 文件中:
STDMETHODIMP CMyATLObject::EVAL( DOUBLE* x, long AddressOfFunc )
{
*x = toto<FCTPTR>(*((FCTPTR) AddressOfFunc)) ;
return S_OK;
}
MyStupidEvaluator.h 包含:
#pragma once
template<typename F>
double toto( F f )
{
return f(0.0) ;
}
这只是一个模板函数,它返回任何函数对象的零值,即承认 () 运算符的类型名(或类)。
现在,这在编译后给了我一个 dll。
这就是 c++ 部分的全部内容。现在,我在 VBA 和 VBA 中引用了这个 dll:
a) 我定义了一个函数
Public Function F(ByVal x As Double) As Double
F = x * x - 2 * x + 1
End Function
b) 和一个子
Public Sub Draft1()
Dim ENGINE As MyTestProjectLib.MyATLObject
Set ENGINE = New MyTestProjectLib.MyATLObject
Dim x As Double
x = 0#
Call ENGINE.EVAL(x, AddressOf F)
Sheets("Test1").Range("Value_at_0").Offset(0, 0).Value = x
End Sub
c) 执行这个子程序会给我,在工作表“Test1”的 V“alue_at_0”(这里只是一个单元格)范围内,函数 F 的 0.0 处的值。
我总是这样工作:toto 模板函数在这里是微不足道的(评估为 0.0),但通常它可能是一个数值积分例程,或者是一个求根例程,需要 c++ 来提高速度;由于 AddressOf VBA 关键字,我一直通过它们的地址传递 VBA 函数:这给了我一个 long,我将它传递给我的 ATL 方法 EVAL,我将这个 long 转换为函数指针 (FCTPTR) p,然后应用我的例程“ toto" 到 *p,这给了我一个双倍,我将它传递回我的 ATL 方法。
这很酷,一切正常,但是......我觉得这太糟糕了!而且真的很不雅。这就是为什么我想做以下事情:
在 ATL 端“以某种方式”设计一个接口,一个
interface IMyFunction : IDispatch
这将由 VBA 类 VBAClass1 在 VBA 中实现(通过 VBA 的实现),并将该 VBA 类的实例传递给我以前的 VBA 方法的新版本,以在 0.0 处执行评估。
我的问题是:我根本不是 ATL 方面的专家,也不是界面创建方面的专家:我已经成功地在界面创建方面做了真正愚蠢/琐碎的事情,好吧,但我真的不知道如何设计界面做我想做的是:
ATL 中的一个接口(根据定义,它只有方法,通过 ATL 构造!)将具有“某物”扮演类成员的角色,成员跟踪 VBA 函数仍将通过 ATL 传递给他方法。
任何帮助将不胜感激,伙计们。
这是我第一次来这里,如果消息不是完美/最佳形式,请提前道歉。
先感谢您。
拉夫