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加载失败");
        }
    }
}
相关推荐
离陌在学C#1 小时前
C# 事件(Event)详解:从概念到实战
开发语言·c#
Terra.K2 小时前
Java异常学习[特殊字符]
java·开发语言·学习
rockey6273 小时前
C#脚本引擎之AScript与Flee对比
c#·.net·script·eval·动态脚本
葡萄城技术团队3 小时前
InfluxDB 2\.x 深度解析:核心架构、Flux 函数与制造业落地指南(三)
java·开发语言·架构
counting money3 小时前
Java IO流详解:从InputStream到文件操作实战
java·开发语言·python
wuyk5554 小时前
98.C语言易混难点:字符数组与字符串指针的底层差异
c语言·开发语言·c++·stm32·嵌入式硬件·算法
峥无4 小时前
从0到1手撕红黑树:封装实现 my_map 与 my_set(SGI-STL 源码级深度解析)
开发语言·c++·笔记·算法·stl
波特率1152004 小时前
C++新特性---属性说明符与标准属性
开发语言·c++
程序员小八7774 小时前
上海百度B端java后端日常实习一面
java·开发语言
wp123_14 小时前
IPX8 防水 Type‑C连接器:安费诺 124018792112A 与 TONEVEE TY48087‑24A 技术梳理
c语言·开发语言