FiveM Exports in Lua: exports('name', fn) und 'No such export'
Wie Exports in FiveM Lua definiert und aufgerufen werden, die fxmanifest exports und server_exports Stile, und wie man 'No such export'-Fehler behebt, die durch Start-Reihenfolge oder die falsche Seite verursacht werden.
Ein Skript ruft ein anderes auf und die Konsole antwortet:
No such export getCount in resource my_inventoryDieser Artikel zeigt, wie Exports in Lua definiert und aufgerufen werden, die zwei Wege, sie zu deklarieren, und die üblichen Gründe, warum dieser Fehler erscheint.
Defining an export
Ein Export lässt eine Ressource eine Funktion den anderen anbieten. Der einfache Weg ist die exports-Funktion in einem Skript:
-- my_inventory/server/main.lua
local function getCount(source, item)
-- ...
return 5
end
exports('getCount', getCount)Du kannst auch die Funktion inline übergeben:
exports('getCount', function(source, item)
return 5
end)Das ist alles. Es gibt nichts zu fxmanifest.lua hinzufügen, und der Export existiert auf welcher Seite auch immer das Skript läuft: Lege es in ein Server-Skript und es ist ein Server-Export, lege es in ein Client-Skript und es ist ein Client-Export.
Der Manifest-Stil
Ältere Ressourcen deklarieren Exports in fxmanifest.lua und definieren eine schlichte globale Funktion mit dem gleichen Namen:
-- fxmanifest.lua
fx_version 'cerulean'
game 'gta5'
server_exports { 'getCount' }
exports { 'getOwnedCount' }-- server script
function getCount(source, item)
return 5
endexports { … }listet Client-Exports auf.server_exports { … }listet Server-Exports auf.
Dies funktioniert immer noch, und viele ESX- und QBCore-Ressourcen verwenden es. Die zwei Stile konfligieren nicht, daher kann eine Ressource sie mischen. Für neuen Code ist exports('name', fn) einfacher, da die Funktion und der Export zusammen leben, und du kannst nicht eine Zeile im Manifest vergessen. Denke daran, dass fxmanifest.lua der aktuelle Manifest-Dateiname ist: siehe fxmanifest vs __resource.lua.
Aufrufen eines Exports
Von jeder anderen Ressource auf der gleichen Seite:
local count = exports['my_inventory']:getCount(source, 'water')Die Punkt- und Doppelpunkt-Versionen sind das Gleiche, solange der Name ein gültiger Lua-Identifier ist:
local count = exports.my_inventory:getCount(source, 'water')Verwende die Klammer-Form, wenn der Ressourcen-Name einen Bindestrich hat, wie exports['qb-core']:GetCoreObject(). Der Aufruf ist synchron: Es gibt den Wert der Funktion zurück, und es kann warten, wenn die Funktion wartet.
Tipp: Argumente und Rückgabewerte reisen zwischen Ressourcen, daher werden Tabellen kopiert. Eine Tabelle, die du von einem Export erhältst, zu ändern, ändert nicht die eigenen Daten der anderen Ressource. Funktionen in einer zurückgegebenen Tabelle funktionieren immer noch, da sie zurück in den Besitzer aufrufen.
Warum du „No such export" bekommst
No such export getCount in resource my_inventoryÜberprüfe diese, in dieser Reihenfolge:
- Die Ressource ist nicht gestartet. Öffne die Konsole und führe
ensure my_inventoryaus. Wenn es nicht startet, repariere das zuerst. - Sie startete nach dem Aufrufer. Der Export existiert nur, wenn der Besitzer seine Skripte geladen hat. Siehe start order in server.cfg und lege den Besitzer über den Skripten, die sie verwenden.
- Der Name ist falsch geschrieben. Export-Namen sind Groß-/Kleinschreibung sensibel:
getCountundGetCountsind unterschiedlich. - Falsche Seite. Ein Server-Skript kann einen Client-Export nicht aufrufen, und umgekehrt. Der Fehler sieht gleich aus.
- Der Export ist deklariert, aber die Funktion fehlt. Mit dem Manifest-Stil braucht
server_exports { 'getCount' }eine globale Funktion namensgetCountauf dem Server. Eine lokale Funktion zählt nicht. - Der Besitzer ist ausgefallen oder wurde gestoppt. Wenn es auf einem Skript-Fehler abgestürzt ist, oder du hast es gestoppt, seine Exports sind weg, bis es wieder läuft. Lesen Sie seine Startup-Ausgabe in der Konsole.
Für die realen Versionen dieses Fehlers, siehe No such export GetSharedObject in resource es_extended und QBCore is nil: GetCoreObject.
Machen die Reihenfolge sicher mit Abhängigkeiten
Verlasse dich nicht nur auf die Reihenfolge der ensure-Zeilen. Deklariere die Abhängigkeit im Manifest des Skripts, das den Export aufruft:
dependency 'my_inventory'FiveM startet dann my_inventory zuerst, und weigert sich, deine Ressource zu starten, wenn sie fehlt, mit einer klareren Meldung (could not find dependency).
Umgang mit einer fehlenden Ressource elegant
Wenn eine andere Ressource optional ist, überprüfe seinen Zustand, bevor du es aufrufst:
if GetResourceState('my_inventory') == 'started' then
local count = exports.my_inventory:getCount(source, 'water')
endGetResourceState gibt einen String wie started, stopped, starting oder missing zurück. Es ist der saubere Weg, um eine optionale Integration ohne einen Konsolen-Fehler zu unterstützen.
Aufrufen deiner eigenen Exports
Eine Ressource kann auch ihre eigenen Exports mit ihrem eigenen Namen aufrufen: exports['my_inventory']:getCount(...). Für eine Funktion, die nur in der Ressource verwendet wird, ist eine normale lokale Funktion schneller und einfacher. Exports sind für die Grenze zwischen Ressourcen.
Ein Wort zur Leistung
Jeder Aufruf kreuzt zwischen zwei Ressourcen, daher ist es langsamer als ein normaler Funktionsaufruf. Rufe einen Export nicht in einer eng pro-Frame-Schleife auf, wenn du den Wert einmal lesen und behalten kannst. Das Aufrufen eines paar Mal pro Sekunde ist in Ordnung.
Checkliste
| Symptom | Lösung |
|---|---|
No such export x in resource y |
Starte y und lege es vor den Aufrufer in server.cfg |
| Funktioniert auf dem Server, schlägt auf dem Client fehl | Definiere den Export auch in einem Client-Skript oder rufe ihn vom Server auf |
| Manifest-Stil Export fehlt | Definiere eine globale Funktion mit dem gleichen Namen wie der Manifest-Eintrag |
Kurze Antworten
Wie rufe ich einen Export von einer anderen Ressource auf?
Verwende exports['resource_name']:exportName(args) oder exports.resource_name:exportName(args). Die andere Ressource muss gestartet sein und muss diesen Export auf der gleichen Seite (Client oder Server) definieren.
Brauche ich immer noch Exports in fxmanifest.lua?
Nicht mit exports('name', fn): Es registriert den Export vom Skript selbst. Die Listen exports {} und server_exports {} im Manifest sind der ältere Stil, wo eine globale Funktion nach Name exponiert wird.
Warum funktioniert ein Export auf dem Client, aber nicht auf dem Server?
Client- und Server-Exports sind separat. Ein Export, der in einem Client-Skript definiert ist, existiert nur auf dem Client, und einer, der in einem Server-Skript definiert ist, nur auf dem Server.
Scripts ohne dieses Problem
Item Creator V2Erstelle nutzbare Items mit Animationen, Props, Effekten und mehr — ganz ohne Code.Script ansehen →
Mic PhoneEin faltbares Handy, das sich zum Tablet aufklappt und bis aufs echte Handy des Spielers reicht.Script ansehen →
Shop CreatorBau einen Shop in unter einer Minute — Besitzer, Angestellte, Tresore und Überfälle inklusive.Script ansehen →