Tencent / xLua

xLua is a lua programming solution for C# ( Unity, .Net, Mono) , it supports android, ios, windows, linux, osx, etc.
Other
9.33k stars 2.45k forks source link

lua 调用 c# delegate 报错 #49

Closed wulei closed 7 years ago

wulei commented 7 years ago

我在拿第三方的一个besthttp做了一些调用使用测试,有些疑问,请教一下:

这个是c# code

namespace BestHTTP.WebSocket
{
    public delegate void OnWebSocketOpenDelegate(WebSocket webSocket);
    public delegate void OnWebSocketMessageDelegate(WebSocket webSocket, string message);
    public delegate void OnWebSocketBinaryDelegate(WebSocket webSocket, byte[] data);
    public delegate void OnWebSocketClosedDelegate(WebSocket webSocket, UInt16 code, string message);
    public delegate void OnWebSocketErrorDelegate(WebSocket webSocket, Exception ex);
    public delegate void OnWebSocketErrorDescriptionDelegate(WebSocket webSocket, string reason);

#if (!UNITY_WEBGL || UNITY_EDITOR)
    public delegate void OnWebSocketIncompleteFrameDelegate(WebSocket webSocket, WebSocketFrameReader frame);
#else
    delegate void OnWebGLWebSocketOpenDelegate(uint id);
    delegate void OnWebGLWebSocketTextDelegate(uint id, string text);
    delegate void OnWebGLWebSocketBinaryDelegate(uint id, IntPtr pBuffer, int length);
    delegate void OnWebGLWebSocketErrorDelegate(uint id, string error);
    delegate void OnWebGLWebSocketCloseDelegate(uint id, int code, string reason);

    /// <summary>
    /// States of the underlying browser's WebSocket implementation's state. It's available only in WebGL builds.
    /// </summary>
    public enum WebSocketStates : byte
    {
        Connecting = 0,
        Open       = 1,
        Closing    = 2,
        Closed     = 3
    };
#endif

    public sealed class WebSocket
    {
#region Properties

        /// <summary>
        /// The connection to the WebSocket server is open.
        /// </summary>
        public bool IsOpen
        {
            get
            {
#if (!UNITY_WEBGL || UNITY_EDITOR)
                return webSocket != null && !webSocket.IsClosed;
#else
                return ImplementationId != 0 && WS_GetState(ImplementationId) == WebSocketStates.Open;
#endif
            }
        }

#if (!UNITY_WEBGL || UNITY_EDITOR)
        /// <summary>
        /// Set to true to start a new thread to send Pings to the WebSocket server
        /// </summary>
        public bool StartPingThread { get; set; }

        /// <summary>
        /// The delay between two Pings in millisecs. Minimum value is 100, default is 1000.
        /// </summary>
        public int PingFrequency { get; set; }

        /// <summary>
        /// The internal HTTPRequest object.
        /// </summary>
        public HTTPRequest InternalRequest { get; private set; }

        /// <summary>
        /// IExtension implementations the plugin will negotiate with the server to use.
        /// </summary>
        public IExtension[] Extensions { get; private set; }
#endif

        /// <summary>
        /// Called when the connection to the WebSocket server is estabilished.
        /// </summary>
        public OnWebSocketOpenDelegate OnOpen;

        /// <summary>
        /// Called when a new textual message is received from the server.
        /// </summary>
        public OnWebSocketMessageDelegate OnMessage;

        /// <summary>
        /// Called when a new binary message is received from the server.
        /// </summary>
        public OnWebSocketBinaryDelegate OnBinary;

        /// <summary>
        /// Called when the WebSocket connection is closed.
        /// </summary>
        public OnWebSocketClosedDelegate OnClosed;

这个是lua code

function awake()
print("awake...")
end

local ws = nil
-- local url = "ws://echo.websocket.org"
local url = "ws://115.29.193.48:8088"

function start()
    print("websocket lua start...")
    ws = CS.BestHTTP.WebSocket.WebSocket(CS.System.Uri(url))
    print(ws.IsOpen)

    ws:OnOpen('+', function(ws)
        print("nice!!!~~~~")
    end)
    ws:Open()
end

function update()
    -- print(ws.IsOpen)
end

function ondestroy()
    print("websocket lua destroy")
end

结果如下:

LuaException: [string "LuaBehaviour"]:15: attempt to call a nil value (method 'OnOpen')
stack traceback:
    [string "LuaBehaviour"]:15: in function <[string "LuaBehaviour"]:10>
XLua.LuaEnv.ThrowExceptionFromError (Int32 oldTop) (at Assets/xLua/Src/LuaEnv.cs:360)
XLuaGenDelegateImpl0.Invoke1 ()
LuaBehaviour.Start () (at Assets/_LFramework/Scripts/Common/LuaBehaviour.cs:70)

如果我在update中一直打印:ws.IsOpen,是看得出他在调用链接,最后返回链接上的,但是调用delegate就报错了,是否是我使用者的问题?

Jayatubi commented 7 years ago

delegate可以用'+'么?我以为只有event可以那样写。

chexiongsheng commented 7 years ago

ws.OnOpen = ws.OnOpen + function() end

另外,你那个delegate要加CSharpCallLua

chexiongsheng commented 7 years ago

其实在教程都有,最好去看看

wulei commented 7 years ago

不好意思,教程里面我看歪了。 把delegate的+链接和event混了。

wulei commented 7 years ago

@chexiongsheng

LuaException: [string "WebsocketTest.lua"]:24: attempt to perform arithmetic on a nil value (field 'OnClosed')
stack traceback:
    [string "WebsocketTest.lua"]:24: in function <[string "WebsocketTest.lua"]:10>
XLua.LuaEnv.ThrowExceptionFromError (Int32 oldTop) (at Assets/xLua/Src/LuaEnv.cs:360)
XLuaGenDelegateImpl0.Invoke2 ()
LuaBehaviour.Start () (at Assets/_LFramework/Scripts/Common/LuaBehaviour.cs:70)

教程里面中的是ok的,但是这个是说 on a nil value,已经在delegate中加入CSharpCallLua,而且我调用ws.IsOpen的bool值不会有问题

chexiongsheng commented 7 years ago

你要先判空,空的话直接OnOpen=function。 貌似c#下也是会报错的吧,如果左值为null的话