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加载失败");
        }
    }
}
相关推荐
Sunshine for you8 分钟前
C++中的职责链模式实战
开发语言·c++·算法
@我漫长的孤独流浪21 分钟前
Python编程核心知识点速览
开发语言·数据库·python
qq_4160187228 分钟前
C++中的状态模式
开发语言·c++·算法
2401_8845632429 分钟前
模板代码生成工具
开发语言·c++·算法
code 小楊35 分钟前
yrb 1.5.0 正式发布:Python 极简国内下载加速与全景可视化终端体验!
开发语言·python
2401_8319207443 分钟前
C++代码国际化支持
开发语言·c++·算法
m0_672703311 小时前
上机练习第51天
数据结构·c++·算法
2401_851272991 小时前
自定义内存检测工具
开发语言·c++·算法
章鱼丸-1 小时前
DAY31 文件的拆分和写法
开发语言·python
左左右右左右摇晃1 小时前
Java并发——synchronized锁
java·开发语言