2011-06-16 13 views
5

ठीक है, मैं थोड़ी देर के लिए इस पर खुदाई कर रहा हूं और इनपुट की तलाश में हूं।जावा .NET इंटरऑप

मुझे जावा एप्लिकेशन की आवश्यकता है जो मूल पुस्तकालयों को लोड और अनलोड कर सकता है, पर्याप्त सरल, सी/सी ++/जावा/स्क्रिप्ट/एक्जिक्यूटिव/आदि। जेएनआई और अन्य सुविधाओं में निर्मित कोई वास्तविक समस्या नहीं है।

हालांकि, मुझे .NET पुस्तकालयों को भी लोड करने की क्षमता की आवश्यकता है, यह पागल निराशाजनक रहा है।

जावा:

this.Lib = (LibHandler)Native.loadLibrary("MyLib", LibHandler.class); 

सीपीपी:

#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; 
    } 
} 

यह लगातार विफल हो जाएगा भी प्रणाली द्वारा लोड करने के लिए मेरा पहला attept रूप में नीचे है JNI का उपयोग करें और एक सी ++ आवरण कहते थे , मैं फ़ाइलों को स्वैप कर सकता हूं ताकि MyLib.dll वास्तव में 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) 

मैं सोचा मैं एक COM ऑब्जेक्ट के रूप में सी # पुस्तकालय संकलन और है कि जिस तरह से यह कॉल करने के लिए कोशिश करना चाहते हैं, अफसोस:

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) 

सी # कोड:

ActiveXComponent comp = new ActiveXComponent("MyLib.Class1"); 

साथ विफल:

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 पंजीकृत है ered, मैं इसे oleview.exe से ब्राउज़ कर सकता हूं, लेकिन मैं इसे vbScript से नहीं बुला सकता ... मैं उस पर उलझन में हूं, इसलिए मैं पूरी तरह से विचारों से बाहर हूं, यह वास्तव में पूरे दिन मेरे दिमाग को रैक कर रहा है।

मैं चाहें कॉम से दूर होने की, लेकिन मैं implmentation काफी सरल (पुस्तकालयों अभ्यस्त हमारे द्वारा विकसित किया जा, तो मैं में C/C++ कोड का एक समूह छोड़ने के लिए नहीं करना चाहती रखने की जरूरत है वीबी 6 डेवलपर्स की गोद)।

मैं सीएलआई सी ++ कार्यान्वयन विधि पर वापस जाने के साथ ठीक हूं, क्योंकि यह इतना सरल है क्योंकि लगभग कोई भी इसे कर सकता है।

किसी भी विचार की अत्यधिक सराहना की जाएगी, धन्यवाद।

संपादित करें:

मैं System.LoadLibrary उपयोग नहीं कर सकते, अभ्यस्त मुझे एक नियत वर्ग करता है के साथ Native.LoadLibrary तरह पुस्तकालयों उतारना करते हैं।

+0

:

नीचे आप नेट रैंडम वर्ग का उपयोग कर Javonet का नमूना कोड प्राप्त कर सकते हैं (यह है कि तीसरे पक्ष के पुल के साथ आप न केवल अपने कस्टम DLL लेकिन पूर्ण .NET फ़्रेमवर्क तक पहुँच प्राप्त सूचना के लिए महत्वपूर्ण है) संभावित डुप्लिकेट [जावा से कॉलिंग सी # कोड?] (http://stackoverflow.com/questions/50398/calling-c-sharp-code-from-java) – Unsigned

उत्तर

6

JNI सी ++ कोड के साथ सही ढंग से काम हो रही समाप्त, मैं सी ++ को 32-बिट के रूप में संकलित कर रहा था, लेकिन मैं 64-बिट जेवीएम चला रहा हूं जो इस बेहद अस्पष्ट त्रुटि का कारण बन रहा था।

मैं भी .NET (लाइब्रेरी जीएसी में नहीं था) से त्रुटियों में भाग गया, इसलिए जावा को सही ढंग से पकड़ने/रिपोर्ट करने के लिए सुनिश्चित करें, ऐसा लगता है कि जावा में बेकार अपवादों को लपेटा नहीं जा सकता है।

मैं शायद जल्द ही एक संसाधन के रूप में इस ऑनलाइन पोस्ट करेंगे, किया जा रहा है के रूप में कई JNI < -> नेट इंटरॉप ट्यूटोरियल रास्ता overcomplicated हैं (आमतौर पर जोड़ने क्या अत्यंत अनावश्यक परतों हो रहा है)।

4

मैं अगर यह मदद करता है पता नहीं है, लेकिन ओपन सोर्स प्रोजेक्ट IKVM आप नेट के लिए अपने जावा आवेदन परिवर्तित विपरीत करने के लिए, की अनुमति देता है:

IKVM.NET is an implementation of Java for Mono and the Microsoft .NET Framework. It includes the following components:

* A Java Virtual Machine implemented in .NET 
* A .NET implementation of the Java class libraries 
* Tools that enable Java and .NET interoperability 
+1

अगर मैं गलत हूं तो मुझे सही करें, लेकिन IKVM नहीं है मैं क्या चाहता हूं इसके विपरीत है? मैं अपना जावा एप्लिकेशन लेता हूं और इसे मूल रूप से एक में बदल देता हूं।नेट एक जो ... हाँ मुझे लगता है कि उस बिंदु पर मैं .NET पुस्तकालयों को कॉल कर सकता हूं, हालांकि यह हमारे क्रॉस प्लेटफार्म समर्थन को तोड़ देगा (नहीं कि हमें * निक्स सिस्टम पर .NET पुस्तकालयों की आवश्यकता है, लेकिन यह मूल रूप से हमें एक कांटा लेने की आवश्यकता होगी मेरे जावा प्रोग्राम में, जो मुझे लगता है कि थोड़ी मूर्खतापूर्ण है)। यदि कोई वास्तविक अन्य तरीका नहीं है तो मुझे लगता है कि मैं उस मार्ग पर जा सकता हूं। – StrangeWill

+0

ठीक है, ठीक है, मैंने एक .NET DLL को एक .jar में बदलने की कोशिश की और इसके साथ समाप्त हुआ: 'थ्रेड में अपवाद "मुख्य" java.lang.NoClassDefFoundError: cli/system/Object', [googling it] (http://comments.gmane.org/gmane.comp.java.ikvm.devel/2437) दिखाता है कि यह इस तरह से नहीं किया जा सकता है। मैं अपने डीएलएल को बदलने के लिए ikvmstub का उपयोग कर रहा हूं, क्या मुझे ऐसा करने का एक और तरीका है? – StrangeWill

+0

अफसोस की बात है, आप सही हैं, मुझे यह कथन मिला: "ikvmstub द्वारा उत्पन्न जार फ़ाइलों में जावा क्लास और इंटरफेस शामिल हैं जो .NET कक्षाओं से मेल खाते हैं, लेकिन इसमें कोई वास्तविक कोड नहीं है। इसमें जावा कंपाइलर को संतुष्ट करने के लिए पर्याप्त मात्रा है, और इसे जावा एप्लिकेशन की जांच करने की अनुमति दें। " यह वह पृष्ठ है जहां मैंने इसे पाया: http://sourceforge.net/apps/mediawiki/ikvm/index.php?title=Tutorial – yms

1

आपका COM इंटरऑप कोड लगभग सही दिखता है। हालांकि, अगर आप coclass देर बाध्य जब तक आप इस तरह वर्ग पर डिफ़ॉल्ट इंटरफेस को परिभाषित का दृष्टांत नहीं कर सकते हैं:

[Guid("3ECD46AE-E8F4-4B62-B9DC-DD7F6CB435E2"), 
ClassInterface(ClassInterfaceType.None), 
ComDefaultInterface(typeof(ITest)), 
ComSourceInterfaces(typeof(ITestEvents)), 
ComVisible(true)] 
public class Class1 : ITest 
+0

बहुत बहुत धन्यवाद, COM इंटरऑप अभी भी काफी उपयोगी है और मुझे यकीन है कि मैं भविष्य में इसे फिर से लागू करने वाले मुद्दों में भाग लेगा। – StrangeWill

5

आप को बेनकाब करने के अपने दृष्टिकोण उचित है एक विधि है। निश्चित रूप से जेएनआई से सी ++/सीएलआई तक जा रहा है और फिर .NET COM ऑब्जेक्ट्स का उपयोग करके इस तरह के संचार को संभालने की कोशिश करने से अधिक विश्वसनीय समाधान और बनाए रखना आसान है।

वैसे भी जिनके पास किसी भी विधि को कॉल करने, रेफ/आउट तर्कों को पार करने, जेनेरिक तरीकों को कॉल करने, फ़ील्ड सेट करने, अपवादों को संभालने, अनुक्रमित गुणों को प्राप्त करने, अनुक्रमित गुण आदि प्राप्त करने जैसी अधिक जटिल आवश्यकताएं हैं। आदि .. मुझे लगता है कि कस्टम देशी रैपिंग काम नहीं करेगा, कम से कम तर्कसंगत समय और लागत में नहीं।

आप इस तरह की आवश्यकताओं या सिर्फ है, तो possbilities के बारे में पता होना करने के लिए नेट पुल करने के लिए तीसरे पक्ष के जावा पर एक नजर है कृपया:

इन आईकेवीएम के अनुसार इस मामले के लिए दो अधिक उपयुक्त हैं। वे पुल आपको सीधे अपने जावा कोड में किसी भी .NET लाइब्रेरी का उपयोग करने देते हैं। वे ज्ञात जाल के लिए अंतर्निहित डेटा प्रकार के अनुवाद और अन्य तंत्र सहित सभी निर्दिष्ट परिचालन/परिदृश्यों और बहुत कुछ संभालते हैं।

जेएनबीजिज थोड़ा अधिक भारी और अधिक महंगा है। हालांकि इसमें बिज़टॉक जैसे एंटरप्राइज़ सिस्टम के लिए कुछ समर्पित प्लगइन्स हैं। दूसरी तरफ जैवनेट बहुत हल्का एक जार-फ़ाइल समाधान बहुत आसान एपीआई के साथ आधा मूल्य है। दूसरा बड़ा अंतर यह है कि जेवनेट प्रॉक्सी कक्षाओं के बिना काम करता है, इसलिए आपको किसी भी रैपर को जेनरेट करने की आवश्यकता नहीं है जिसे आप प्रतिबिंब शैली के साथ .NET कहते हैं जबकि जेएनबीज द्वारा आप प्रॉक्सी कक्षाएं उत्पन्न कर सकते हैं जो आपको दृढ़ता से टाइप इंटरफ़ेस देता है लेकिन इसमें अधिक समय और प्रयास लगता है । मेरी राय में यह लचीलापन को थोड़ा कम कर देता है क्योंकि मुझे इस पर नियंत्रण रखना पसंद है कि हुड के नीचे क्या होता है और जेवोनेट के साथ आप आसानी से अपने स्वयं के दृढ़ता से टाइप किए गए लिपटे को आसानी से बना सकते हैं।

मुझे लगता है कि यह अभी भी लोकप्रिय नहीं है लेकिन एकल मशीन समाधान के लिए यह एक महान दृष्टिकोण है जो मूल प्रदर्शन के साथ .NET और JAVA के बीच अंतर को कवर करता है। यह webservices द्वारा निष्पादन निष्पादन समय के प्रतिशत का अंश है और किसी भी उच्च स्तरीय क्लाइंट-सर्वर आधारभूत संरचना की आवश्यकता नहीं है। मेरे परीक्षणों में सीधे .NET में विशेष कोड निष्पादित करने में लगभग 30% अधिक समय लगता है (यह बहुत आकर्षक है)।

यह सुनना अच्छा है कि आप अपना केस हल करें और मुझे आशा है कि यह पोस्ट जावा के साथ दूसरों को .NET इंटरऑप मुद्दों में मदद करेगा।

public void GenerateRandomNumber() throws JavonetException 
{ 
     NObject objRandom = Javonet.New("System.Random"); 
     int value = objRandom.invoke("Next",10,20); 

     System.out.println(value); 
} 
संबंधित मुद्दे