使用JNA加载依赖的.NET程序集

时间:2014-08-30 17:19:35

标签: c# .net dll dependencies jna

我有一个.NET(C#)dll,它通过Unmanaged Exports导出函数,这些函数正由Java应用程序使用。

这个C#dll(让我们称之为A.dll)有另一个托管依赖项F3BC4DNI.dll。

因此,依赖链如下:Java类< - JNA< - A.dll< - F3BC4DNI.dll

不要说所有dll都包含在应用程序bin文件夹中。

但是,所有java二进制文件都在一个名为javaw.exe的进程下运行,然后当我尝试通过JNA使用A.dll时,它在javaw.exe路径中寻找F3BC4DNI.dll 而不是与A.dll相同的文件夹,可以在Process Monitor中看到:

Dependency being searched inside javaw directory

我的猜测是A.dll(.NET)在查找依赖项时假设进程路径

我尝试了很多可能的解决方案,例如设置PATH环境var,设置JNA库路径,还尝试使用Assembly.LoadFrom在A.dll中明确加载B.dll程序集。

运行Java应用程序时结果始终相同:

Exception in thread "main" java.lang.Error: Invalid memory access
    at com.sun.jna.Native.invokePointer(Native Method)
    at com.sun.jna.Function.invokePointer(Function.java:470)
    at com.sun.jna.Function.invokeString(Function.java:651)
    at com.sun.jna.Function.invoke(Function.java:395)
    at com.sun.jna.Function.invoke(Function.java:315)
    at com.sun.jna.Library$Handler.invoke(Library.java:212)

当我将这些dll复制到Program Files \ Java ... bin \文件夹时,它可以工作,但显然我不想在生产中以这种方式部署它。

毕竟,我唯一假设的是它不是Java或JNA方面的问题,因为它与.NET相关的依赖,所以我必须以某种方式告诉javaw。 exe依赖于.NET依赖文件。

1 个答案:

答案 0 :(得分:0)

[...]I have to somehow tell javaw.exe that .NET dependencies are in another folder.

就像我怀疑的那样,当手动告诉.NET依赖关系时,问题已经解决,使用答案from this post

/// <summary>
/// Initializes a new instance of the <see cref="T:System.Object"/> class.
/// </summary>
static A()
{
    AppDomain.CurrentDomain.AssemblyResolve += (sender, e) =>
    {
        var path = Path.Combine(Directory.GetCurrentDirectory(), "bin\\F3BC4DNI.DLL");
        return Assembly.LoadFile(path);
    };
}