Хорошо, я некоторое время копался в этом и ищу информацию.
Мне нужно Java-приложение, которое может загружать и выгружать собственные библиотеки, достаточно простые, C / C ++ / Java / Scripts / Executables / и т.д. нет реальной проблемы с использованием JNI и других встроенных функций.
Тем не менее, мне нужна возможность загружать библиотеки .NET, это было сумасшедшим разочарованием. Моей первой попыткой было использовать JNI и вызвать оболочку C ++, как показано ниже:
Java:
this.Lib = (LibHandler)Native.loadLibrary("MyLib", LibHandler.class);
CPP:
#include <jni.h>
#using <MyLibCSharp.dll>
#include <vcclr.h>
#include <msclr\marshal.h>
using namespace msclr::interop;
using namespace System::Runtime::InteropServices;
using namespace System;
extern "C"
{
JNIEXPORT jstring JNICALL Java_Test(JNIEnv * env)
{
marshal_context ^ context = gcnew marshal_context();
const char* str4 = context->marshal_as<const char*>(CSharp::Class1::Test());
jstring js = env->NewStringUTF(str4);
return js;
}
JNIEXPORT jstring JNICALL Java_Test2(JNIEnv * env, jobject jobj)
{
marshal_context ^ context = gcnew marshal_context();
const char* str4 = context->marshal_as<const char*>(CSharp::Class1::Test());
jstring js = env->NewStringUTF(str4);
return js;
}
}
Это может постоянно не загружаться даже системой, я могу поменять файлы так, что MyLib.dll на самом деле является C #, и он успешно загружает его (но не может найти какие-либо функции, поскольку он не является родным C библиотека, и я не думаю, что .NET может экспортировать как C ++), поэтому у меня нет проблем с расположением файлов.
Exception in thread "main" java.lang.UnsatisfiedLinkError: Unable to load library 'MyLib.dll': The specified module could not be found.
at com.sun.jna.NativeLibrary.loadLibrary(NativeLibrary.java:163)
at com.sun.jna.NativeLibrary.getInstance(NativeLibrary.java:236)
at com.sun.jna.Library$Handler.<init>(Library.java:140)
at com.sun.jna.Native.loadLibrary(Native.java:379)
at com.sun.jna.Native.loadLibrary(Native.java:364)
at EntryPoint.main(EntryPoint.java:31)
Я подумал, что попробую скомпилировать библиотеку C # как объект COM и вызвать ее таким образом, увы:
ActiveXComponent comp = new ActiveXComponent("MyLib.Class1");
Сбой с:
Exception in thread "main" com.jacob.com.ComFailException: Can't co-create object
at com.jacob.com.Dispatch.createInstanceNative(Native Method)
at com.jacob.com.Dispatch.<init>(Dispatch.java:99)
at com.jacob.activeX.ActiveXComponent.<init>(ActiveXComponent.java:58)
at EntryPoint.main(EntryPoint.java:33)
C # код:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Runtime.InteropServices;
namespace MyLib
{
[Guid("4F3A0A13-4D2B-4DE6-93EA-D6861C230290"),
ComVisible(true)]
public interface ITest
{
[DispId(1)]
string Test();
}
[Guid("A78C5820-3E4B-49B3-8C8E-63DD12346410"),
InterfaceType(ComInterfaceType.InterfaceIsIDispatch),
ComVisible(true)]
public interface ITestEvents
{
}
[Guid("3ECD46AE-E8F4-4B62-B9DC-DD7F6CB435E2"),
ClassInterface(ClassInterfaceType.None),
ComSourceInterfaces(typeof(ITestEvents)),
ComVisible(true)]
public class Class1 : ITest
{
public string Test()
{
return "This is my C# DLL COM returning a string! heh!";
}
}
}
Я вижу, что COM зарегистрирован, я могу просматривать его с помощью oleview.exe, но я не могу вызвать его из vbScript ... Я запутался в этом, так что у меня совершенно нет идей, это действительно весь день ломал мне голову
Я бы хотел бы уйти от COM, но мне нужно, чтобы реализация была достаточно простой (библиотеки не будут разрабатываться нами, поэтому я не хочу отбрасывать кучу C / C ++ код на коленях разработчиков VB6).
Хорошо бы вернуться к методу реализации CLI C ++, поскольку это так просто, что почти каждый может это сделать.
Любые идеи будут очень признательны, спасибо.
Edit:
Я не могу использовать System.LoadLibrary, не позволяю мне выгружать библиотеки, как это делает Native.LoadLibrary с назначенным классом.