关于IL2CPP编译,C#调用WindowsAPI的方法(已解决2019.12.2)

    在unity中我使用了c#的系统函数,System.Threading.Mutex 这个函数

    在Windows上进行跨进程通信,需要读取一个互斥量,观察unity运行的TCP服务器有没有正常启动

    这时使用IL2CPP的方式进行编译发布,发现运行时在如下行出现异常:

   mutex = new System.Threading.Mutex(true, "test_mutex", out have);

     使用try,catch捕获异常,显示函数调用异常,也就是找不到函数的实现。

     通过查看IL2CPP编译之后的C++源码发现,函数实现出现问题,并未转换成功

     具体代码如下:

using System.Collections;
using System.Collections.Generic;
using UnityEngine;

public class TestMutex : MonoBehaviour
{
    // Start is called before the first frame update
    System.Threading.Mutex mutex;
    void Start()
    {
        CreateMutex();
        ReleaseMutex();
        CloseMutex();
    }

    // 创建互斥量
    public void CreateMutex()
    {
        bool have = false;
        mutex = new System.Threading.Mutex(true, "test_mutex", out have);
    }

    // 释放互斥量
    public void ReleaseMutex()
    {
        mutex.ReleaseMutex();
    }

    // 释放资源
    public void CloseMutex()
    {
        mutex.Close();
    }
}

二、解决方案

   使用system.threading.mutex默认的库,既然存在问题,

   而我们需要解决的问题是使用互斥量进行进程通信

   所以我们可以使用windows自带的mutex API

   在Windows中有四个API

   CreateMutex();

   OptenMutex();

   RelaseMutex();

   CloseHandle();

   原型如下:

WINBASEAPI
_Ret_maybenull_
HANDLE
WINAPI
CreateMutexW(
    _In_opt_ LPSECURITY_ATTRIBUTES lpMutexAttributes,
    _In_ BOOL bInitialOwner,
    _In_opt_ LPCWSTR lpName
    );

   

WINBASEAPI
_Ret_maybenull_
HANDLE
WINAPI
OpenMutexA(
    _In_ DWORD dwDesiredAccess,
    _In_ BOOL bInheritHandle,
    _In_ LPCSTR lpName
    );
WINBASEAPI
BOOL
WINAPI
ReleaseMutex(
    _In_ HANDLE hMutex
    );
WINBASEAPI
BOOL
WINAPI
CloseHandle(
    _In_ _Post_ptr_invalid_ HANDLE hObject
    );

   所以只要在unity中引入上述DLL,同时进行使用上述API,就能够达成我们所需要的目的

   C#使用引入windowsAPI的流程如下:

  1、 确定WindowsAPI所在DLL

  2、重新定义函数的原型

  3、在C#中调用对应函数

例子如下:

using System.Collections;
using System.Collections.Generic;
using System.Runtime.InteropServices;
using UnityEngine;

public static class Import
{

    [DllImport("kernel32.dll")]
    public static extern System.IntPtr CreateMutexW(
        System.IntPtr lpMutexAttributes,
        bool bInitialOwner,
         string lpName
    );

    [DllImport("kernel32.dll")]
    public static extern bool ReleaseMutex(System.IntPtr hMutex);

    [DllImport("kernel32.dll")]
    public static extern bool CloseHendle(System.IntPtr hObject);
}

public class TestMutex : MonoBehaviour
{
    // Start is called before the first frame update
    System.IntPtr mutex;
    void Start()
    {
        CreateMutex();
        ReleaseMutex();
        CloseMutex();
    }

    // 创建互斥量
    public void CreateMutex()
    {
        mutex = Import.CreateMutexW(System.IntPtr.Zero, true, "testMutex");
    }

    // 释放互斥量
    public void ReleaseMutex()
    {
        Import.ReleaseMutex(mutex);
    }

    // 释放资源
    public void CloseMutex()
    {
        Import.CloseHendle(mutex);
    }
}

    通过DllImport操作引入动态库,需要添加 using System.Runtime.InteropServices;

    把函数原型中 指针 转换为 System.IntPtr;

    把函数原型中 字符串 转换为 String

    把函数原型中BOOL  转换为 bool

    就能够实现函数的快速调用了

你可能感兴趣的:(c#编程)