C++動態庫封裝C#庫,驗證動態庫環境

Yzi321發表於2024-11-13

windows 平臺、VS2019、x64

當C++編譯的動態庫提供給C#的開發人員時,需要實現一個C#的庫使用委託去呼叫C++動態庫。

當C#開發人員連結使用C#的動態庫時,如果沒有完全複製C++動態庫所依賴的其他動態庫時,就會出現執行報錯。

但是報錯時,不會提示缺少了什麼庫,這裡在C#的中增加一個函式,去檢測環境下缺少了什麼動態庫,便於排查問題。

實現

public class DynamicLibraryDetector
{
    [DllImport("kernel32.dll", CharSet = CharSet.Auto)]
    private static extern uint GetDllDirectory(uint nBufferLength, System.Text.StringBuilder lpBuffer);

    private static readonly List<string> RequiredDlls = new List<string>
    {
        "yourLibrary1.dll",
        "yourLibrary2.dll",
        "yourLibrary3.dll",
        // 新增所有依賴的 DLL 名稱
    };

    /// <summary>
    /// Checks the existence of all required DLLs in the current working directory, DLL directory, and PATH environment variable.
    /// Throws a DllNotFoundException if any required DLL is missing.
    /// </summary>
    /// <exception cref="DllNotFoundException">
    /// Thrown if one or more required DLLs are not found.
    /// </exception>
    public static void Check()
    {
        List<string> missingDlls = new List<string>();
        List<string> foundDlls = new List<string>();

        // 獲取當前 DLL 目錄
        string currentDllDirectory = GetCurrentDllDirectory();

        foreach (var dll in RequiredDlls)
        {
            // 檢查當前工作目錄
            if (File.Exists(dll))
            {
                foundDlls.Add(dll);
                continue;
            }

            // 檢查當前 DLL 目錄
            string fullPathInCurrentDir = Path.Combine(currentDllDirectory, dll);
            if (File.Exists(fullPathInCurrentDir))
            {
                foundDlls.Add(dll);
                continue;
            }

            // 檢查 PATH 環境變數中的所有路徑
            string[] paths = Environment.GetEnvironmentVariable("PATH").Split(';');
            bool foundInPath = false;

            foreach (var path in paths)
            {
                string fullPath = Path.Combine(path, dll);
                if (File.Exists(fullPath))
                {
                    foundInPath = true;
                    foundDlls.Add(dll);
                    break;
                }
            }

            if (!foundInPath)
            {
                missingDlls.Add(dll);
            }
        }

        if (missingDlls.Count > 0)
        {
            throw new DllNotFoundException($"Missing DLL files: {string.Join(", ", missingDlls)}. Please make sure to copy them to the application directory or set the correct path in PATH. ");
        }
    }

    private static string GetCurrentDllDirectory()
    {
        const int bufferSize = 1024;
        var buffer = new System.Text.StringBuilder(bufferSize);
        GetDllDirectory((uint)bufferSize, buffer);
        return buffer.ToString();
    }
}

使用

DynamicLibraryDetector.Check();

相關文章