You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

从Rust调用C# DLL时start_monitor函数依赖缺失问题

解决Rust调用C# DLL时NAudio依赖缺失的问题

问题原因

当从非.NET进程(如Rust)加载.NET Framework DLL时,.NET的程序集加载器会优先在Rust可执行文件的目录而非C# DLL所在目录搜索依赖。这就是为什么C#控制台调用正常(工作目录是C# DLL目录),但Rust调用失败的核心原因。

可行解决方案

1. 复制依赖到Rust输出目录

直接把NAudio.Wasapi.dll、NAudio.dll等所有NAudio相关依赖文件,复制到Rust项目的target/debug(调试模式)或target/release(发布模式)目录下,和Rust生成的可执行文件放在一起。

2. 切换Rust程序的工作目录

在加载C# DLL前,将Rust程序的工作目录切换到C# DLL所在目录,让.NET加载器能在该目录找到依赖。修改Rust代码:

extern crate libloading;
use libloading::{Library, Symbol};
use std::env;

type SayHelloFunc = unsafe extern "C" fn();

fn main() {
    // 切换到C# DLL所在目录
    env::set_current_dir("C:\\path\\to\\MicMonitorDllNetFramework")
        .expect("Failed to switch working directory");
    
    let lib_path = "MicMonitorDllNetFramework.dll";
    let lib = unsafe { Library::new(lib_path).expect("Could not load the library") };
    
    unsafe {
        let myname: Symbol<SayHelloFunc> = lib.get(b"my_name\0").expect("Could not load function my_name");
        let mics: Symbol<SayHelloFunc> = lib.get(b"start_monitor\0").expect("Could not load function start_monitor");

        myname();
        mics();
    }
}

3. 在C# DLL中添加程序集解析逻辑

在C# DLL的类中添加静态构造函数,注册程序集解析事件,强制从C# DLL所在目录加载依赖。修改C#代码:

using NAudio.CoreAudioApi; 
using NAudio.CoreAudioApi.Interfaces; 
using RGiesecke.DllExport; 
using System; 
using System.Collections.Generic; 
using System.Diagnostics; 
using System.IO;
using System.Reflection;
using System.Runtime.InteropServices;

namespace MicMonitorDllNetFramework {
public class MicMonitor
{
    // 静态构造函数,注册程序集解析事件
    static MicMonitor()
    {
        AppDomain.CurrentDomain.AssemblyResolve += (sender, args) =>
        {
            // 获取当前DLL所在目录
            string currentDllDir = Path.GetDirectoryName(Assembly.GetExecutingAssembly().Location);
            // 拼接依赖DLL的路径
            string dllName = new AssemblyName(args.Name).Name + ".dll";
            string dllPath = Path.Combine(currentDllDir, dllName);
            
            if (File.Exists(dllPath))
            {
                return Assembly.LoadFrom(dllPath);
            }
            return null;
        };
    }                  
    
    [DllExport("start_monitor", CallingConvention = CallingConvention.Cdecl)]
    public static void GetActiveApplications()
    {
        // 原有代码不变...
    }

    [DllExport("my_name", CallingConvention = CallingConvention.Cdecl)]
    public static void MyName()
    {
        Console.WriteLine("Hello world!");
    }
}}

重新编译C# DLL后,无论Rust程序在哪运行,都会自动从C# DLL所在目录加载依赖。

4. 将C# DLL和依赖打包成单文件

使用Costura.Fody工具将NAudio依赖嵌入到C# DLL中,生成一个包含所有依赖的单文件DLL,无需单独携带依赖文件:

  • 在C#项目中安装Costura.Fody NuGet包
  • 重新编译C# DLL,生成的DLL会包含所有NAudio依赖
  • 直接在Rust中调用这个单文件DLL即可

内容的提问来源于stack exchange,提问作者sid patra

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.22 08:44:55