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加载失败");
        }
    }
}
相关推荐
m0_6860416114 小时前
C++中的适配器模式变体
开发语言·c++·算法
清风~徐~来14 小时前
【视频点播系统】WebSocketpp 介绍及使用
开发语言
恒者走天下14 小时前
cpp c++辅导星球价格调整
c++
爱吃大芒果15 小时前
Flutter for OpenHarmony 实战:mango_shop 路由系统的配置与页面跳转逻辑
开发语言·javascript·flutter
学***542315 小时前
如何轻松避免网络负载过大
开发语言·网络·php
RANCE_atttackkk15 小时前
Springboot+langchain4j的RAG检索增强生成
java·开发语言·spring boot·后端·spring·ai·ai编程
梵刹古音15 小时前
【C语言】 格式控制符与输入输出函数
c语言·开发语言·嵌入式
Acrelhuang15 小时前
工商业用电成本高?安科瑞液冷储能一体机一站式解供能难题-安科瑞黄安南
大数据·开发语言·人工智能·物联网·安全
hello 早上好15 小时前
03_JVM(Java Virtual Machine)的生命周期
java·开发语言·jvm
沐雪架构师15 小时前
LangChain 1.0 Agent开发实战指南
开发语言·javascript·langchain