我有一个ATL简单对象MyATLObject,仅具有一个方法:
STDMETHODIMP CMyATLObject::EVAL(DOUBLE* x, long AddressOfFunc)
{
*x = toto<FCTPTR>(*((FCTPTR) AddressOfFunc)) ;
return S_OK;
}
其中托托是一个模板功能由
#pragma once
template<typename F>
double toto(F f)
{
return f(0.0) ;
}
定义且其中FCTPTR被定义为
的typedef双(__stdcall * FCTPTR)(双);
我ATL方法消耗用于存储TOTO的结果双x和长AddressOfFunc其为VBA函数的AddressOf。
这传递VBA函数ATL方法的地址。这是相当可怕的。如何才能做到这一点 - 将VBA函数传递给ATL方法,否则,例如通过在ATL端定义一个接口?
非常感谢。
////////////////////////////////////////////// ////////////////////////////////////////////////// ////////////////////////////////////////////////// ////////////////////////////////////
第一版我的问题:
我实际上做以下操作:创建一个ATL/COM项目,添加名为MyATLObject “简单ATL对象” 将其与:在IDL文件
1):
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:
一)我定义一个函数
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++的寻根程序;我是通过他们的地址传递VBA函数的,这要归功于AddressOf VBA关键字:这给了我很长的一段时间,我传递给了我的ATL方法EVAL,我将这个long函数指针(FCTPTR)p转换,并且将我的例程“ toto“to * p,这给了我一个双倍的回报,我回到我的ATL方法。
这很酷,一切正常,但...我觉得这太可怕了!而且非常不雅。这就是为什么我要做到以下几点:
设计“莫名其妙”的对ATL侧接口,
interface IMyFunction : IDispatch
,将在VBA用VBA类VBAClass1来实现(通过VBA的器具),并将该VBA类的实例传递给我以前的VBA方法的新版本,以便在0.0处执行评估。我的问题是:我不是ATL的专家,也不是在界面创建:我成功地在界面创建中做了真正的愚蠢/微不足道的事情,好吧,但我真的不知道如何去做设计接口做我想做的事情,那就是:
ATL中的一个接口(根据定义,它只有通过ATL构造的方法!),它具有扮演类的成员角色的“东西” ,会员跟踪VBA功能仍然需要通过ATL方法传递给他。
任何帮助将不胜感激,乡亲们。
这是我第一次来这里,如果消息不是完美/最佳的形式,那么很抱歉。
预先感谢您。
拉斐
谢谢你的回答。我仍然是一个新手,所以我没有真正明白你的意思:正如我所解释的,我确实希望传递一个可调用的接口指针作为参数,是的,因此我在问我该如何设计它接口,因为我现在无法自己回答这个问题,对ATL几乎一无所知。 – 2012-08-07 14:29:46
例如,在我的情况下,你将如何设计界面? – 2012-08-07 15:06:35
我提到的情景,这是可行的。我没有显示的代码段,对不起。关于这两者的第一个建议 - 你将在ATL项目中定义回调接口(在IDL中),你可以找到[如何在VBA中实现这个接口](http://stackoverflow.com/questions/3171324/implementing- my-own-interface-in-vba-error-object-module-needs-to-implement)就在这里。 – 2012-08-07 16:51:16