I have a resource that registers a new event handler, which takes a function as a parameter. Since this function is a cfx_functionReference, I need to use Citizen.InvokeFunctionReference to execute it. However, when I retrieve the return value, I get "??" instead of the expected result.
How can I fix this? The example below demonstrates my issue:
AddEventHandler("events", function(fun)
local entity = 123
local reference = Citizen.GetFunctionReference(fun)
local sargs = msgpack.pack({ entity })
local result = Citizen.InvokeFunctionReference(
reference,
sargs, sargs:len()
)
print("result:", result, type(result))
end)
RegisterCommand("events", function(args)
TriggerEvent("events", function(entity)
return entity == 123
end)
end, false)
In this case the output will be result: ?? string.
P.S. I found out that in order to retrieve the return value, it must be a string. However, it still returns something like '??value'. Is '??' a meaningful value, or can I simply use result:sub(3) to remove it?
The ?? at the beginning of the result is due to the response being packed using msgpack. You need to unpack it to get the actual value. Here’s the corrected code:
local unpackedResult = msgpack.unpack(result) print("result:", unpackedResult, type(unpackedResult))
This should give you the correct return value instead of the ??
I was initially testing passing a function as a parameter in an event from the client to the server. So, even though functions can’t be passed from the client to the server via events, I thought InvokeFunctionReference was necessary also for client-client events. Thanks anyway for pointing out how I can improve my code.
As for exports, I actually need to use events because I have to store additional information in a centralized way, which exports don’t allow since they use the context of the resource that requests the export rather than the one that provides it. But thanks for the suggestion anyway
Client → Server (or vice-versa) function calls are sadly not possible
Curious what you mean by this, the function will get called in the context of the “host” or “called” resource, and it should have all the data you need.
What I mean is that I need to call an event that passes a table containing, among other things, the function like the one in the example above. This table is then stored in the resource that registers the event and later checked in a thread with an infinite while loop. This is why i need events instead of exports