Unity客户端与后台通信

在做Unity游戏开发时,与后台的通信是必不可少的。我们可以用c#自带的WebRequest来与后台通信,但是这种通信方式效率是比较低的,特别是当游戏需要多人在线时,用c#来进行网络通信会完全无法满足要求。这个时候就需要用C或者C++来与后台进行通信了。所以在这儿,我主要讲一下Unity客户端如何通过C与后台服务器进行通信。

生成DLL文件

Unity中调用C的方法是通过调用用C生成的DLL库来实现的,所以我们先看看如何生成DLL文件。首先打开Visual Stdio新建Win32项目。
Unity客户端与后台通信_第1张图片

我先新建了一个简单的demo,实现一个加法的功能。添加DllDemo.h的头文件和DllDemo.c的源文件。这个两个文件的代码如下。

DllDemo.h文件

/*_declspec( dllexport )作是是将函数定义为导出函数,就是说函数要被外部程序调用。*/
#define EXPORTS_DEMO _declspec( dllexport )
/*定义个加法操作的方法*/
extern EXPORTS_DEMO int AddFun(int a, int b);

DllDemo.c文件,实现方法是注意要加上在.h文件中定义的EXPORTS_DEMO

#include "stdafx.h"
#include "DllDemo.h"
EXPORTS_DEMO int AddFun(int a, int b)
{
    return (a + b);
}

然后点击生成,注意要生成x86和x64两个平台,生成后我们就可以在项目文件中找到生成的dll文件了

Unity客户端与后台通信_第2张图片

通过Unity调用DLL文件

新建一个Unity项目,创建Plugins文件下,Plugins文件夹下面分别创建x86和x64两个子文件夹,将对应dll文件分别拖入响应的文件夹中
Unity客户端与后台通信_第3张图片

下面我们就可以调用这dll里面的方法了,调用的代码如下。

[DllImport("DllDemo")]
static extern int AddFun(int x, int y);

注意这里的方法名要与dll中声明的方法名一致,这样我们就可以在Unity中调用这个方法了。

通过DLL与后台进行通信

通过一个简单的Demo我们了解了如何在Unity中调用C,现在可以开始说说如何在Unity中通过c与后台进行通信。我们需要使用到socket的知识。

c的socket知识网上有很详细的资料,一般的过程如下。

    mclose = FALSE;
    call = callback;

    WSADATA  wsaData;
    WSAStartup(WINSOCK_VERSION, &wsaData);

    g_soClient = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);

    if (INVALID_SOCKET == g_soClient) 
    {
        WSACleanup();
    }

    SOCKADDR_IN addrServer;
    addrServer.sin_addr.S_un.S_addr = inet_addr(STR_SERVER_IP);
    addrServer.sin_family = AF_INET;
    addrServer.sin_port = htons(INT_SERVER_PORT);

    int iResult;
    int iTimeOut = 3000;
    setsockopt(g_soClient, SOL_SOCKET, SO_RCVTIMEO, (char*)&iTimeOut, sizeof(iTimeOut));
    iResult = connect(g_soClient, (SOCKADDR *)&addrServer, sizeof(SOCKADDR_IN));
    if (SOCKET_ERROR == iResult) 
    {
        puts("Failed to connect server!(Error: %d)\r\n");
        WSACleanup();
        ReCreateSocket();
    }

我们可以在socket中开一个子线程,不断的接收和发送消息。那么Unity中如何接socket收返回来的消息呢? 这个时候我们可以用回调来接受,下面我们就来看看通过回调来使C和Unity之间传递数据。

我们首先在DllDemo.h中定义定义好回调函数,已经设置回调的方法。我定义的回调的返回参数为char*类型,这里可以随意定义成自己需要返回的数据类型。

typedef void *Callback (char* buffer);
extern EXPORTS_DEMO void SetCallback(Callback callback);

然后在DllDemo.c是实现SetCallback函数

EXPORTS_DEMO void SetCallback(Callback callback) 
{
    mCallback=callback;
}

现在我们能就可以使用这个mCallback回调方法来返回我们需要传递的数据了,通过socket接收到数据后,调用mCallback(data),就可以将数据返回了。接下来我们来看看Unity中的c#代码如何接收这个回调方法。

    public delegate void Callback(string buf);
    public Callback callback;

    [DllImport("DllDemo", EntryPoint = "SetCallback", CallingConvention = CallingConvention.Cdecl)] 
    public extern static void SetCallback(RoomCallback callback);


    /*在需要回调的地方,实现回调函数的委托*/
    Callback = GameCallbackFunction;
    SetCallback(Callback);

    public void GameCallbackFunction(string buffer)
    {
        Debug.Log(buffer);
    }

通过委托的方式,我们就可以接收C实时传送过来的数据了。

你可能感兴趣的:(Unity3D技术专栏)