У меня есть DLL.NET (С#), которая экспортирует функции через Unmanaged Exports, который потребляется Java-приложением.
Эта DLL С# (пусть называется A.dll) имеет другую управляемую зависимость F3BC4DNI.dll.
Таким образом, цепочка зависимостей похожа: Java class <- JNA <- A.dll <- F3BC4DNI.dll
Не нужно говорить, что все библиотеки DLL включены вместе в папку bin приложения.
Однако все java файлы выполняются под процессом javaw.exe, а затем, когда я пытаюсь использовать A.dll через JNA, он ищет F3BC4DNI.dll внутри пути javaw.exe вместо той же папки, что и A.dll, что может быть в Process Monitor:
Я предполагаю, что A.dll(.NET) предполагает путь к процессу при поиске зависимостей.
Я пробовал множество возможных решений, таких как настройка среды PATH var, настройка пути библиотеки JNA, а также я попытался явно загрузить сборку B.dll внутри A.dll с помощью Assembly.LoadFrom
.
При запуске приложения 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)
Когда я копирую эти dlls в папку Program Files\Java... bin \, это работает, но, очевидно, я не хочу разворачивать его таким образом в процессе производства.
В конце концов, единственное, что я предполагаю, это то, что это не проблема с Java или JNA, потому что это зависимость от.NET, поэтому мне нужно как-то сказать javaw.exe, что зависимости.NET находятся в другой папке.
[...]I have to somehow tell javaw.exe that .NET dependencies are in another folder.
Так же, как я подозревал, при ручном сообщении.NET, где есть зависимость, проблема была решена, используя ответ из этого сообщения.
/// <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);
};
}