MDN’s new design is in Beta! A sneak peek: https://blog.mozilla.org/opendesign/mdns-new-design-beta/

Declaring and Using Callbacks

这篇翻译不完整。请帮忙从英语翻译这篇文章

C函数偶尔将函数指针作为参数,它们通常用作回调。.在这些情况下,js-ctypes允许您传递常规JavaScript函数作为回调。这是非常强大的,因为它允许本地代码透明地调用JavaScript。

警告: 回调必须在它们注册的同一线程上调用。js-ctypes中没有并发逻辑,因此在其他线程上调用回调会导致事情崩溃。

先决条件

声明回调

A callback is declared by using ctypes.FunctionType. The first argument is the calling convention, the second argument is the return type, and the third is an array of arguments the callback expects.

The return type of the javascript callback must match the return type declared, otherwise js-ctypes will throw an error saying "unexpected return type".

范例

例子 1

这个回调返回bool并有两个参数。

var myFuncTypeDeclaration = ctypes.FunctionType(ctypes.default_abi, ctypes.bool, [ctypes.int, ctypes.voidptr_t]);

function myJSCallback(cInt, cPtr) {
    return true; // as the return of the FunctionType was ctypes.bool we must make our javascript callback return bool otherwise js-ctypes will throw error saying unexpected type return
}

var myCCallback = myFuncTypeDeclaration.ptr(myJSCallback);

例子 2

这个回调返回void,没有参数。当void是返回类型时,javascript回调一定不能返回,或者它应该返回未定义。

var myFuncTypeDeclaration = ctypes.FunctionType(ctypes.default_abi, ctypes.void_t, []);

function myJSCallback() {
    return undefined; // as the return of the FunctionType was ctypes.void_t we must return undefined OR dont return at all otherwise js-ctypes will throw an error saying unexpected type
}

var myCCallback = myFuncTypeDeclaration.ptr(myJSCallback);

使用回调

Since callbacks are function pointers in C, js-ctypes has special handling for function pointer types. Consider the following code:

function myJSCallback(foo, bar) { .... };
var funcType = ctypes.FunctionType(...);
var funcPtrType = funcType.ptr;
var regularFuncPtr = funcPtrType();
var callback = funcPtrType(myJSCallback); 

js-ctypes detects that funcPtrType is a type of function pointer, and adds a special case to its constructor. In the ordinary case, invoking the type object creates a regular CData object containing a pointer to the data. However, if the first argument is a function, js-ctypes creates a special object (known internally as a CClosure) that wraps the JavaScript function within an ordinary C function. This can all be done in a single line of code, like so:

var callback = ctypes.FunctionType(...).ptr(function(...) {...});
Note: The use of .ptr() here isn't a method call; we're accessing a property that dynamically creates a callable object, and then invoking the result.

If two arguments are passed to the callback constructor, the second is used as the this parameter:

function myJSCallback() {
  alert(this.message);
};

var receiver = { message: 'hi there!' };
var callback = funcPtrType(myJSCallback, receiver); // alerts with 'hi there' when the callback is invoked

If three arguments are passed to the callback constructor, the third argument is used as a sentinel value which the callback returns if an exception is thrown. The sentinel value must be convertible to the return type of the callback:

function myJSCallback() {
  throw "uh oh";
};

var callback1 = funcPtrType(myJSCallback, null, -1); // Returns -1 to the native caller when the exception is thrown.
Warning: You must store a reference to the callback object as long as the native code might call it. If you don't, the GC might collect the relevant data structures, and the browser will crash when native code attempts to invoke your callback.

参数和返回值

js-ctypes automatically handles the conversion between JavaScript and C value representations. Before the JavaScript callback function is invoked, js-ctypes converts the arguments passed by the caller to JavaScript values. Where possible, js-ctypes will convert arguments to primitive types. For arguments of complex types, temporary CData objects will be created.

The return value is converted in a similar manner.

文档标签和贡献者

 此页面的贡献者: xgqfrms-GitHub
 最后编辑者: xgqfrms-GitHub,