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加载失败");
        }
    }
}
相关推荐
AC赳赳老秦26 分钟前
公开音频转写信息提取:OpenClaw 处理发布会与听证会文本并提取核心决策信息
大数据·开发语言·汇编·数据库·人工智能·deepseek·openclaw
@yanyu66638 分钟前
C编译器安装与第一个C程序
c语言·开发语言
落魄实习生1 小时前
Agent Scope Java 2.x 系列【2】 ReActAgent
java·开发语言
智鸟科技GemeOpen开发者智能设备1 小时前
智能插座二次开发如何接入Home Assistant,从零开始完整工程实现(Python+React)
开发语言·python·物联网·react.js·智能家居
疯狂成瘾者1 小时前
海康 Artemis 接口对接
开发语言·lua
2601_962218611 小时前
C++中decltype关键字的实现
开发语言·c++
hqyjzsb1 小时前
法律 Prompt 干货:搭建合同审查提示词要包含哪些要素
开发语言·人工智能·python·职场和发展·数据分析·prompt·业界资讯
孙启超1 小时前
【AI开发之Rust】第 19 课:UniFFI 导出核心能力
开发语言·后端·rust
2601_966949652 小时前
股票池发生变化后,如何高效更新行情数据?从全量刷新到增量同步
开发语言·python·数据分析·pandas·量化交易·股票数据·quantdash
繁华的地方不一定留下你的脚印2 小时前
C++ std::variant 与 std::visit:安全保存多种类型,写清每个处理分支
开发语言·c++