# Builtin - 函数指针与原生回调

## `DeleteInstance(obj)`

声明：function

删除由 `MakeInstance` 生成的函数指针

<!-- tags: 外部调用 函数指针 回调 释放指针 释放函数指针 delete callback 函数指针与原生回调 删除 移除 -->

| 参数  | 类型    | 说明                        |
| ----- | ------- | --------------------------- |
| `obj` | pointer | `MakeInstance` 生成的指针。 |

返回：Boolean，删除成功返回真，否则返回假。

### 示例

删除尚未包装调用的函数指针：

```tsl
func_ptr := MakeInstance(thisFunction(ReturnOne), "cdecl", 0);
echo DeleteInstance(func_ptr);

function ReturnOne(): integer;
begin
    return 1;
end;
// 输出：1
```

## `MakeInstance(fun, mode, threadmode)`

声明：function

将 TSL 函数或类成员函数生成可供 C 等外部程序调用的函数指针

<!-- tags: 外部调用 函数指针 生成函数指针 回调 callback cdecl stdcall 多线程 函数指针与原生回调 创建 生成 -->

传入的 TSL 函数必须声明参数类型和返回类型。当前文档说明其返回类型支持单精度浮点、双精度浮点和整数。

| 参数         | 类型              | 说明                                                                     |
| ------------ | ----------------- | ------------------------------------------------------------------------ |
| `fun`        | String\|TFunction | TSL 函数或 TSL 类成员函数。                                              |
| `mode`       | string            | 可选。`cdecl` 或 `stdcall`，默认 `cdecl`；Win32 下须与宿主回调约定一致。 |
| `threadmode` | integer           | 可选。`0` 为单线程，`1` 为多线程单模，`2` 为多线程多模，默认 `0`。       |

返回：pointer，等同于 C 语言函数指针，可供外部程序调用。

### 示例

将 TSL 函数包装成外部函数指针，并在 TSL 内通过 `external` 函数指针声明重新调用：

```tsl
func_ptr := MakeInstance(thisFunction(Add), "cdecl", 0);
wrapped_func := function(a: integer; b: integer): integer; external func_ptr;
echo func_ptr <> nil, "\n";
echo ##wrapped_func(3, 4), "\n";
wrapped_func := nil;
echo DeleteInstance(func_ptr);

function Add(a: integer; b: integer): integer;
begin
    return a + b;
end;
// 输出：1
// 输出：7
// 输出：1
```

也可以用函数名取得指针：`MakeInstance(findFunction("Add"), "cdecl", 0)`。

## `findFunction(name)`

声明：function

按名称查找函数或 unit，找不到时返回 `0`

<!-- tags: 函数指针与原生回调 查找 搜索 lookup 获取 查询 -->

| 参数   | 类型         | 说明                 |
| ------ | ------------ | -------------------- |
| `name` | string\|unit | 函数名称或 unit 名称 |

返回：tfunction\|unit\|integer

### 示例

范例01：查找并调用函数

```tsl
func := findFunction("addValues");
echo call(func, 2, 3);
// 输出：5

function addValues(a, b);
begin
    return a + b;
end;
```

## `findFunction(name, target)`

声明：function

从对象或类中查找方法，找不到时返回 `0`

<!-- tags: 函数指针与原生回调 查找 搜索 lookup 获取 查询 -->

| 参数     | 类型           | 说明     |
| -------- | -------------- | -------- |
| `name`   | string         | 方法名称 |
| `target` | object\|tclass | 对象或类 |

返回：tfunction\|integer

### 示例

范例01：查找并调用对象方法

```tsl
obj := new Calculator();
func := findFunction("add", obj);
echo call(func, 2, 3);
// 输出：5

type Calculator = class
public
    function add(a, b);
    begin
        return a + b;
    end;
end;
```

## `findOverLoad(p_n, function_name, obj)`

声明：function

按方法名和参数个数查找对象或类中的重载方法

<!-- tags: 函数指针 函数重载 方法查找 对象 查找 搜索 lookup callback introspection -->

| 参数            | 类型           | 说明                                         |
| --------------- | -------------- | -------------------------------------------- |
| `p_n`           | integer        | 要匹配的方法参数个数                         |
| `function_name` | string         | 要查找的方法名                               |
| `obj`           | object\|tclass | 对象实例或类类型；传入类类型时只能查找类方法 |

返回：tfunction\|integer

### 示例

```tsl
func := findOverLoad(2, "add", new OverloadProbe());
echo func.do(1, 2), "\n";

type OverloadProbe = class
public
    function add(a, b); overload;
    begin
        return a + b;
    end;
    function add(a); overload;
    begin
        return a + 10;
    end;
end;
// 输出：3
```

## `thisFunction(target)`

声明：function

返回当前函数或指定函数、对象方法、类方法的函数值

<!-- tags: 函数指针与原生回调 返回 获取 -->

| 参数     | 类型 | 说明                                               |
| -------- | ---- | -------------------------------------------------- |
| `target` | any  | 可选。函数名、对象方法或类方法，省略时返回当前函数 |

返回：tfunction

### 示例

范例01：取得指定函数并调用

```tsl
func := thisFunction(addValues);
echo call(func, 2, 3);
// 输出：5

function addValues(a, b);
begin
    return a + b;
end;
```
