编辑:
我有一个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定义为
二(__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;
}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)执行此子命令时,在工作表“alue_at_0”的V "Test1“范围内(这里只是一个单元格),函数F的值为0.0。
我总是这样工作: toto模板函数在这里很简单(求值为0.0),但一般来说,它可以是一个数值积分例程,或者是快速需要c++的根查找例程;由于AddressOf VBA关键字,我也在通过它们的地址传递VBA函数:这给了我一个很长的时间,我把这个长函数指针(FCTPTR) p转换成函数指针(FCTPTR) p,并将我的例程"toto“应用到*p,这给了我一个双倍,然后我把它传递给了我的ATL方法。
很酷,一切正常,但是.我觉得这很可怕!而且真的很不雅。这就是为什么我想做以下几件事:
设计ATL侧的“某种方式”接口,
interface IMyFunction : IDispatch这将由VBA类VBAClass1在VBA中实现(通过VBA的实现),并将该VBA类的一个实例传递给我以前的VBA方法的一个新版本,以便在0.0时执行评估。
我的问题是:我根本不是ATL方面的专家,也不是界面创建方面的专家:我已经成功地在界面创建中做了非常愚蠢/琐碎的事情,好吗,但我真的不知道如何设计界面,做我想做的事情,也就是说:
ATL中的一个接口(根据定义,它只有方法,通过ATL构造!)这将有“某些东西”扮演一个类的成员的角色,成员跟踪一个VBA函数仍然要通过ATL方法传递给他。
各位,任何帮助都将不胜感激。
这是我第一次来这里,如果消息不是完美的/最佳的形式,请提前道歉。
提前谢谢你。
拉斐尔
发布于 2012-08-07 14:10:47
您应该重新考虑关于AddressOfFunc参数和回调地址的所有内容。在设计COM接口并希望提供回调时,需要将可调用的COM接口指针作为参数(相关讨论)传递,这样COM类将调用其方法--这将要求您的VBA类实现此接口(相关问题)。如果您不希望在VBA端实现接口,另一种选择是设计带有事件的ATL类(连接点),这样COM类将触发一个事件,调用方将在那里处理它的回调活动。
函数的普通地址在这里是行不通的,当您不得不抛出一些东西以使它们甚至编译时,您应该怀疑它。
UPD.这提供了有关如何回拨VB代码的示例:从C++/ATL类实现VBScript (VB6,VBA)回调的三种方法
https://stackoverflow.com/questions/11846036
复制相似问题