我有一个名为JsSetCallback
的方法,它被定义为:
function JsSetCallback(Instance: JsValueRef; const CallbackName: UnicodeString; Callback: JsNativeFunction; CallbackState: Pointer; UseStrictRules: Boolean = True): JsValueRef;
对于它的第三个参数,我必须指定一个JsNativeFunction
回调,它被定义为:
type
JsNativeFunction = function(callee: JsValueRef; isConstructCall: bool; arguments: PJsValueRef; argumentCount: Word; callbackState: Pointer): JsValueRef; stdcall;
现在,假设我有一个名为Window_Atob
的JsNativeFunction
方法,假设我希望它成为JsSetCallback
方法的第三个参数。我会写:
function Window_Atob(Callee: JsValueRef; IsConstructCall: bool; Args: PJsValueRefArray; ArgCount: Word; CallbackState: Pointer): JsValueRef; stdcall;
begin
// ...
end;
JsSetCallback(JsCreateObject, 'atob', @Window_Atob, nil);
一切都会好起来的。现在,让我们假设Window_Atob
是一个类的一部分,像这样:
type
TTestObject = class(TObject)
public
function Window_Atob(Callee: JsValueRef; IsConstructCall: bool; Args: PJsValueRefArray; ArgCount: Word; CallbackState: Pointer): JsValueRef; stdcall;
end;
function TTestObject.Window_Atob(Callee: JsValueRef; IsConstructCall: bool; Args: PJsValueRefArray; ArgCount: Word; CallbackState: Pointer): JsValueRef; stdcall;
begin
// ...
end;
procedure TForm1.Button1Click(Sender: TObject);
begin
TestObject := TTestObject.Create;
JsSetCallback(JsCreateObject, 'atob', @TestObject.Window_Atob, nil);
TestObject.Free;
end;
这样的调用将在第15行失败,并出现以下编译器错误:E2036 Variable required
。这个错误是由我调用@TestObject.Window_Atob
触发的。
Embarcadero defines this compiler error为“当你试图获取表达式或常量的地址时”。然而,我不知道如何解决这个问题。如果Window_Atob
方法在一个对象中,是否可以得到它的指针地址?
2条答案
按热度按时间ijxebb2r1#
一个方法有一个隐藏的
Self
参数,这就是为什么你不能使用你的TTestObject.Window_Atob
。只是签名不对。如果您尝试将
TTestObject.Window_Atob
转换为JsNativeFunction
,则会出现编译器错误“E2009 Incompatible types:“常规过程和方法指针”。现在,
Self
参数指向方法所属(或“操作”)的对象(=类的示例)。如果你有一个不需要与特定对象关联的方法,你可以将它声明为一个 *class方法 *:
现在它将不再有指向特定对象的隐藏
Self
参数。相反,它将有一个隐藏的Self
参数指向类本身!因此,这种方法也会有错误的签名。但是如果你把它声明为一个 static 类方法,它就不会有任何隐藏参数。从本质上讲,方法变成了一个普通的过程或函数,但在类的范围内:
现在
TTestObject.Window_Atob
与您的程序类型兼容。显然,将方法设为类方法意味着您不能再在其中访问
Self
。但这是另一回事。yv5phkfx2#
JsSetCallback()
需要一个独立的函数,而不是一个类方法。你不能使用非静态类方法,因为它有一个隐藏的Self
参数,JsNativeFunction
没有考虑。因此,您可以使用独立函数,也可以使用静态类方法(如Andreas Rejbrand's answer中所示)。
不过,还有另一个选择。
JsSetCallback()
似乎有一个用户定义的CallbackState
参数,该参数被传递到回调函数中。如果是这样,那么你可以使用一个代理函数作为回调函数,将你的对象指针传递给代理,然后代理可以调用你的类方法在对象上,例如: