我有一个.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中看到:
我的猜测是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依赖文件。
答案 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);
};
}