C#调用 C++ DLL 加载地址方式选择

1. SetDllDirectory(全局通用型,全局生效)

适用场景 :所有 C++ DLL 集中在一个子目录,全局生效

cs 复制代码
using System;
using System.IO;
using System.Runtime.InteropServices;

class GlobalDllDemo
{
    // 导入SetDllDirectory API
    [DllImport("kernel32.dll", CharSet = CharSet.Unicode)]
    static extern bool SetDllDirectory(string lpPathName);

    // 声明要调用的任意C++ DLL方法(全局生效,所有这类声明都能找到)
    [DllImport("TestDll.dll")]
    static extern int GetVersion();

    static void Main()
    {
        // 1行代码设置全局DLL目录(所有C++ DLL都从这个目录找)
        SetDllDirectory(Path.Combine(AppDomain.CurrentDomain.BaseDirectory, "dll"));

        // 直接调用任意C++ DLL方法,自动从上面的目录查找
        Console.WriteLine("TestDll版本:" + GetVersion());
    }
}
2. LoadLibraryEx(精准控制型,针对具体dll文件设定)

适用场景:不同 DLL 在不同子目录(LoadLibraryEx)

cs 复制代码
using System;
using System.IO;
using System.Runtime.InteropServices;

class SpecificDllDemo
{
    // 导入LoadLibraryEx API
    [DllImport("kernel32.dll", CharSet = CharSet.Unicode)]
    static extern IntPtr LoadLibraryEx(string lpFileName, IntPtr hFile, uint dwFlags);
    const uint LOAD_WITH_ALTERED_SEARCH_PATH = 0x00000008;

    // 声明要调用的指定C++ DLL方法
    [DllImport("TestDll.dll")]
    static extern int GetVersion();

    static void Main()
    {
        // 1行代码仅加载指定的DLL(精准控制单个DLL)
        LoadLibraryEx(
            Path.Combine(AppDomain.CurrentDomain.BaseDirectory, "sdk", "TestDll.dll"),
            IntPtr.Zero,
            LOAD_WITH_ALTERED_SEARCH_PATH
        );

        // 仅这个指定的DLL能被找到,其他目录的DLL仍找不到
        Console.WriteLine("TestDll版本:" + GetVersion());
    }
}

适用场景:手动管理 DLL 生命周期(LoadLibraryEx+FreeLibrary)

cs 复制代码
using System;
using System.IO;
using System.Runtime.InteropServices;

class DllLifeCycleDemo
{
    // 导入核心API:加载+卸载DLL
    [DllImport("kernel32.dll", CharSet = CharSet.Unicode)]
    static extern IntPtr LoadLibraryEx(string lpFileName, IntPtr hFile, uint dwFlags);
    
    [DllImport("kernel32.dll")]
    static extern bool FreeLibrary(IntPtr hModule);

    // 声明要调用的DLL方法
    [DllImport("TestDll.dll")]
    static extern int GetVersion();

    // 关键常量:修改搜索路径
    const uint LOAD_WITH_ALTERED_SEARCH_PATH = 0x00000008;

    static void Main()
    {
        // 1. 手动加载指定DLL(精准控制,获取句柄)
        string dllFullPath = Path.Combine(AppDomain.CurrentDomain.BaseDirectory, "sdk", "TestDll.dll");
        IntPtr dllHandle = LoadLibraryEx(dllFullPath, IntPtr.Zero, LOAD_WITH_ALTERED_SEARCH_PATH);

        if (dllHandle != IntPtr.Zero)
        {
            try
            {
                // 2. 使用DLL方法
                Console.WriteLine("DLL版本:" + GetVersion());
            }
            finally
            {
                // 3. 手动卸载DLL(用完即释放,管理生命周期)
                FreeLibrary(dllHandle);
                Console.WriteLine("DLL已卸载,句柄释放");
            }
        }
        else
        {
            Console.WriteLine("DLL加载失败");
        }
    }
}
相关推荐
hansang_IR8 分钟前
【题解】P9753 [CSP-S 2023] 消消乐
数据结构·c++·算法
liliangcsdn10 分钟前
基于信号强度的稀疏选股算法的探索分析
开发语言·python
竞赛考级题库13 分钟前
202606 青少年等级考试C/C++真题一级 建议答题时长:60min
java·c语言·c++
4SAPI15 分钟前
2026年大模型API接入选型指南:企业与个人用户的架构、稳定性与成本考量
大数据·开发语言·数据库·人工智能·架构·php
lmy_loveF20 分钟前
go 切换go version 版本
开发语言·后端·golang
小白快快跑哦24 分钟前
python-字符串全解(四):字符串方法
开发语言·python·字符串
linx29525 分钟前
阶段五讲义:STL 全貌——扔掉手写循环,学“动词“
c++
fujisheng6611 小时前
拆解 FUI Source Generator:从 Bind 声明到强类型绑定与路由
c#
handler011 小时前
【Linux】动态库、静态库使用与原理
linux·运维·服务器·c++·c·动态库·静态库
raindayinrain1 小时前
c++并发--同步
c++·同步