{
  "category": "User defined functions that are installed with add-ins",
  "display_name": "CALL",
  "entry_kind": "built_in_function",
  "eval_api": {
    "method": "POST",
    "url": "https://handbook.dnacalc.com/api/eval"
  },
  "function_id": "FUNC.CALL",
  "implementation_state": {
    "answer_bank": null,
    "detail": "It calls a procedure in a loaded library, which is the host's to do. DNA Calc recognises the name and calculates no answer.",
    "dnacalc_commit": "9e1884369a678158dd82d3d74188daf986995e87",
    "in_catalogue": false,
    "state": "host",
    "state_label": "Needs a host",
    "summary": "Needs a host that can load code",
    "workbook_corpus": null
  },
  "implementations": [],
  "json_url": "https://handbook.dnacalc.com/api/functions/FUNC.CALL.json",
  "name": "CALL",
  "notes": [],
  "schema": "efh.function-reference/v1",
  "section_order": [
    "what-it-does",
    "try-it",
    "quirks",
    "how-to-implement",
    "version-differences",
    "alternatives"
  ],
  "sections": {
    "alternatives": "\n### Relationships\n\n\n- **[`REGISTER.ID`](FUNC.REGISTER.ID.md)** — the other half of the seam, and the only other\n  member of `call_register_id_family`. `REGISTER.ID` produces the token; `CALL` consumes it.\n  The two pages should be read together.\n- **`REGISTER`** — the macro-sheet function that performs registration with full naming (and\n  which, unlike `REGISTER.ID`, cannot be used on a worksheet). It does not appear in this\n  Handbook's catalog of worksheet functions; it is named here because `CALL`'s first syntax\n  form refers to it.\n- **`UNREGISTER`** — the teardown counterpart, likewise a macro-sheet function.\n- **`EUROCONVERT`** — a category-mate (\"User defined functions that are installed with\n  add-ins\") but nothing like it in kind: `EUROCONVERT` is arithmetic that happens to ship in an\n  add-in, whereas `CALL` is the mechanism by which foreign code becomes callable at all.\n- **XLL add-in functions generally** — every custom function registered by an XLL arrives\n  through this same C API registration machinery. `CALL` is that machinery exposed as a\n  formula.\n\nReaders confuse `CALL` with VBA's `Application.Run` and with `Declare` statements. Those are\nVBA-level constructs with VBA's own marshalling; `CALL` is the worksheet/macro-sheet route into\nthe C API, and its type system is the C API's.\n\n\n",
    "how-to-implement": "\n### Notes for implementers\n\n- `type_text` is a miniature type language, and its exact code set is part of the C API rather\n  than the worksheet function surface. Any faithful implementation must reproduce that\n  language, not invent an equivalent.\n\n\n",
    "quirks": "\n### The danger, stated once and plainly\n\n\nMicrosoft's own page leads with a caution, and this page will too. `CALL` transfers control to\nnative code with no type checking beyond a string the *caller* wrote. If `type_text` does not\nmatch the callee's actual signature, arguments are marshalled wrongly and the process may read\nor write memory it does not own. Microsoft's wording: the function \"is provided for advanced\nusers only\", and using it incorrectly \"may cause errors that will require you to restart your\ncomputer\".\n\nThree specific properties make this worse than an ordinary foreign-function interface:\n\n1. **The contract is a string in a cell.** `type_text` is data, not a compiled declaration.\n   Nothing validates it against the DLL. A one-character error is a memory-safety bug.\n2. **The DLL is named by a string too.** `module_text` is resolved by the operating system's\n   library search, so which file actually loads depends on the machine, not the workbook.\n3. **It is reachable from a document.** A spreadsheet is a document users open casually.\n   `CALL` is the mechanism by which a document can execute native code, which is precisely why\n   Excel confines it (see below) and why it is disabled or blocked in modern configurations.\n\nThe Handbook states this as documented risk and design consequence, not as an observation of a\nparticular Excel build's current defenses, which it has not measured.\n\n\n\n### Result and edge cases\n\n\nWhatever the callee returns, converted according to the first letter of `type_text`. The\nvalue-universe chapter's **raw function return** boundary is exactly the boundary this function\nsits on: an add-in procedure may hand back things — including the C API's empty/\"nil\" token —\nthat a published formula result cannot hold, and a normalization step stands between the two.\nSee [the value universe](../model/01-value-universe.md), where that raw-versus-published gap is\nrecorded as empirically pinned by add-in probes.\n\nThe most important structural constraint is a confinement one. Microsoft states that `CALL`\n\"is only callable from Excel macro sheets\" — it is not a general worksheet function, despite\nappearing in the function catalog. It is also documented as **not available in Excel for the\nweb**, while being listed for Windows, Mac, iPad and Android.\n\n\n\n### Errors\n\n\nMicrosoft's page documents no error-value table for `CALL`. There is a reason for that which is\nworth stating rather than glossing: the failure modes of `CALL` are not, mostly, worksheet\nerrors. A mismatched `type_text` does not produce `#VALUE!` — it produces undefined behaviour\nin the process. The error surface of this function is the operating system's, not Excel's.\n\nWhat the shared model does say: an error value arriving as an argument propagates through\ncoercion unless a function declares otherwise (see\n[coercion and lifting](../model/02-coercion-and-lifting.md)), and `CALL`'s recorded\n`error_collapse_profile` is `None`, meaning no special folding. That is an engine-level\nstatement about the wrapper, not a claim about what a DLL does with what it receives.\n\n\n",
    "sources": "- Microsoft, \"CALL function\" —\n  <https://support.microsoft.com/en-us/office/call-function-32d58445-e646-4ffd-8d5e-b45077a5e995>\n  (the caution quoted above, both syntax forms, all argument descriptions including the\n  first-letter rule for `type_text` and the ordinal form of `procedure`, the macro-sheet\n  confinement, and the platform/version list including the exclusion of Excel for the web).\n- Microsoft, \"REGISTER.ID function\" —\n  <https://support.microsoft.com/en-us/office/register-id-function-f8f0af0f-fd66-4704-a0f2-87b27b175b50>\n  (the registration side of the seam).\n- Handbook `data/presence/FUNC.CALL.json` — the implementing module\n  `earlier-implementation/call_register_id_family.rs` and its surface-dispatch entry.\n\n\n",
    "version-differences": "No comparison between specific Excel builds is recorded here yet. This does not establish that all builds behave alike.",
    "what-it-does": "\n`CALL` is not a function in the sense the rest of this Handbook uses the word. It is a hole in\nthe function surface: an escape from Excel's evaluator into arbitrary native code in a DLL. It\nhas no mathematical definition, no domain, and no result kind of its own. What it returns is\nwhatever the code at the far end returns, marshalled back through a caller-declared type string.\n\n\nNothing, in its own right. `CALL` marshals its arguments into a native call, invokes the\nprocedure, and marshals the return value back into a worksheet value. The \"semantics\" of a\n`CALL` cell are the semantics of the DLL entry point.\n\nThe seam has two forms, and knowing which one you are looking at is the first step in reading\nany `CALL` formula:\n\n```\nCALL(register_id, [argument1], …)                      -- pre-registered\nCALL(module_text, procedure, type_text, [argument1], …) -- self-describing\n```\n\n\n### Arguments\n\n\n- **`register_id`** — a value returned by a previously executed `REGISTER` or `REGISTER.ID`.\n  Not a name, not a handle you can construct: an opaque token produced by this session.\n- **`module_text`** — quoted text naming the DLL containing the procedure. Microsoft's page\n  qualifies this as the Windows form; the function is documented as having a different shape on\n  other environments.\n- **`procedure`** — the function's name within the DLL, *or* its ordinal value. Microsoft's\n  wording is that the ordinal is used \"not [in] text form\" — so this argument position accepts\n  two different kinds of value with different meanings, which is the position most often\n  gotten wrong.\n- **`type_text`** — text specifying the return data type and the data types of all arguments,\n  with the **first letter specifying the return value**. This is the load-bearing argument and\n  the dangerous one. Microsoft's page as fetched does not include the full type-code table;\n  the codes are documented in the Excel C API / XLL developer documentation rather than in the\n  worksheet-function reference.\n- **`argument1, …`** — optional; the values passed through to the procedure.\n\n"
  },
  "signature": {
    "display": "CALL(register_id, [argument1], ...)",
    "parameters": [
      {
        "description": null,
        "name": "register_id",
        "optional": false,
        "repeats": false
      },
      {
        "description": null,
        "name": "argument1",
        "optional": true,
        "repeats": true
      }
    ],
    "trailing_repeats": true
  },
  "sources": {
    "metadata": {
      "admission": {
        "label": "host",
        "reason": "It calls a procedure in a loaded library, which is the host's to do. DNA Calc recognises the name and calculates no answer."
      },
      "arity": {
        "max": 255,
        "min": 1
      },
      "category": "User defined functions that are installed with add-ins",
      "classification": {
        "arg_preparation_profile": "RefsVisibleInAdapter",
        "coercion_lift_profile": "Custom",
        "determinism_class": "ExternalEventDependent",
        "error_collapse_profile": "None",
        "fec_dependency_profile": "ExternalProvider",
        "host_interaction_class": "ApplicationState",
        "kernel_signature_class": "Custom",
        "rich_value_usage": "RichBlind",
        "surface_fec_dependency_profile": "Composite",
        "thread_safety_class": "HostSerialized",
        "volatility_class": "VolatileContextual"
      },
      "descriptions": {
        "long": null,
        "short": "Runs a procedure from a code library (DLL) and gives back its result",
        "short_source": "dna-calc-own"
      },
      "docs": {
        "english_description": "Calls a procedure in a dynamic link library or code resource",
        "microsoft_url": "https://support.microsoft.com/en-us/office/call-function-32d58445-e646-4ffd-8d5e-b45077a5e995"
      },
      "entry_kind": "built_in_function",
      "localized_family_names": null,
      "localized_names": [
        {
          "locale": "ar-SA",
          "name": "إجراء مكالمة"
        },
        {
          "locale": "bg-BG",
          "name": "CALL"
        },
        {
          "locale": "cs-CZ",
          "name": "ZAVOLAT"
        },
        {
          "locale": "da-DK",
          "name": "RING OP"
        },
        {
          "locale": "de-DE",
          "name": "ANRUFEN"
        },
        {
          "locale": "el-GR",
          "name": "CALL"
        },
        {
          "locale": "en-AU",
          "name": "CALL"
        },
        {
          "locale": "en-GB",
          "name": "CALL"
        },
        {
          "locale": "en-US",
          "name": "CALL"
        },
        {
          "locale": "es-ES",
          "name": "LLAMAR"
        },
        {
          "locale": "et-EE",
          "name": "CALL"
        },
        {
          "locale": "fi-FI",
          "name": "SOITA"
        },
        {
          "locale": "fr-FR",
          "name": "CALL"
        },
        {
          "locale": "he-IL",
          "name": "CALL"
        },
        {
          "locale": "hr-HR",
          "name": "CALL"
        },
        {
          "locale": "hu-HU",
          "name": "HÍVÁS"
        },
        {
          "locale": "id-ID",
          "name": "CALL"
        },
        {
          "locale": "it-IT",
          "name": "CALL"
        },
        {
          "locale": "ja-JP",
          "name": "CALL"
        },
        {
          "locale": "ko-KR",
          "name": "통화"
        },
        {
          "locale": "lt-LT",
          "name": "CALL"
        },
        {
          "locale": "lv-LV",
          "name": "CALL"
        },
        {
          "locale": "nb-NO",
          "name": "ANROP"
        },
        {
          "locale": "nl-NL",
          "name": "CALL"
        },
        {
          "locale": "pl-PL",
          "name": "WYWOŁAJ"
        },
        {
          "locale": "pt-BR",
          "name": "CALL"
        },
        {
          "locale": "pt-PT",
          "name": "CHAMAR"
        },
        {
          "locale": "ro-RO",
          "name": "CALL"
        },
        {
          "locale": "ru-RU",
          "name": "ВЫЗВАТЬ"
        },
        {
          "locale": "sk-SK",
          "name": "ZAVOLAŤ"
        },
        {
          "locale": "sl-SI",
          "name": "CALL"
        },
        {
          "locale": "sr-Latn-RS",
          "name": "POZOVI"
        },
        {
          "locale": "sv-SE",
          "name": "RING"
        },
        {
          "locale": "th-TH",
          "name": "CALL"
        },
        {
          "locale": "tr-TR",
          "name": "ÇAĞIR"
        },
        {
          "locale": "uk-UA",
          "name": "CALL"
        },
        {
          "locale": "vi-VN",
          "name": "CALL"
        },
        {
          "locale": "zh-CN",
          "name": "呼叫"
        },
        {
          "locale": "zh-HK",
          "name": "CALL"
        },
        {
          "locale": "zh-TW",
          "name": "CALL"
        }
      ],
      "signature": {
        "display": "CALL(register_id, [argument1], ...)",
        "parameters": [
          {
            "description": null,
            "name": "register_id",
            "optional": false,
            "repeats": false
          },
          {
            "description": null,
            "name": "argument1",
            "optional": true,
            "repeats": true
          }
        ],
        "trailing_repeats": true
      },
      "surface_name": "CALL",
      "version_marker": null,
      "xlcall": {
        "code": "150",
        "symbol": "xlfCall"
      }
    },
    "microsoft": "https://support.microsoft.com/en-us/office/call-function-32d58445-e646-4ffd-8d5e-b45077a5e995"
  },
  "try_it": {
    "formula": "=CALL(\"example.dll\",\"ExampleFunction\",\"J\")",
    "note": "This Excel interface needs a host library. OneCalc cannot load a native library in this preview.",
    "preview_status": "refused"
  },
  "url": "https://handbook.dnacalc.com/functions/CALL.html",
  "variants": [],
  "versions": []
}