2011-04-17 10 views
29

के साथ मिक्सिंग सी # उद्देश्य-सी (कोको) अनुप्रयोग के लिए लाइब्रेरी के रूप में सी # कोड का बड़ा निकाय उपयोग करना चाहता हूं।उद्देश्य-सी

मैंने मोनोमैक प्रोजेक्ट की खोज की जो कोको कोड को लपेटता है, लेकिन इसके बजाय उद्देश्य-सी में लिखा गया मानक कोको एप्लिकेशन होगा, जो लिपटे सी # कोड (अन्य तरीकों के आसपास) को कॉल कर सकता है।

विंडोज़ पर मुझे सी ++/सीएलआई प्रोजेक्ट बनाने के लिए उपयोग किया जाता है जो .NET कोड को लपेटता है और सी/सी ++ आधारित ऐप्स के लिए सादे पुराने सी इंटरफ़ेस निर्यात करता है।

क्या यह हासिल करने का कोई आसान तरीका है?

+0

वास्तव में एक बहुत ही दिलचस्प सवाल है कि। पता नहीं क्या जवाब है, लेकिन मुझे यह देखने में दिलचस्पी है कि लोगों को इसके बारे में क्या कहना है। –

+1

... और यही कारण है कि हमारे पास वोट-अप बटन है। – vidstige

उत्तर

14

जाहिर है, मैक ओएस पर सी ++/सीएलआई जैसी कोई भाषा नहीं है। विंडोज़ पर, सी ++/सीएलआई वास्तव में सीएलआर द्वारा संचालित प्रबंधित कोड के रूप में संकलित करता है, जो देशी कोड चलाता है; चूंकि मैक ओएस मोनो सिस्टम में एकीकृत नहीं है, बल्कि यह दूसरी तरफ है। आपका ऐप मूल है, और यह प्रबंधित कोड होस्ट कर सकता है।

मोनो एक प्रक्रिया के अंदर एक सीएलआर वर्चुअल मशीन होस्ट करने के लिए कार्यों का खुलासा करता है। चूंकि सीएलआर कक्षाएं सीधे आपके सी कोड से अवगत नहीं होती हैं, इसलिए आप प्रतिबिंब जैसी कॉल के माध्यम से वस्तुओं के तरीकों को कॉल करने में सक्षम होंगे।

आधिकारिक साइट पर documentation on how to embed Mono into an application है। चूंकि आप running .NET programs directly में रुचि नहीं रखते हैं, इसलिए आपको "Invoking Methods in the CIL Universe" अनुभाग को पढ़ना चाहिए।मैक ओएस पर, आप के बजाय pkg-config का उपयोग कर के, अपने /Library/Frameworks फ़ोल्डर से मोनो ढांचे के खिलाफ लिंक करना चाहते हैं जाएगा। आप इस बहुत आकर्षक नहीं मिलती है तो

#include <glib/glib.h> 
#include <mono/jit/jit.h> 
#include <mono-metadata/assembly.h> 
#include <mono/metadata/debug-helpers.h> 

// create an app domain 
// http://en.wikipedia.org/wiki/Application_Domain 
MonoDomain* domain = mono_jit_init("Domain"); 

// mandatory Cocoa call to show that Mono and ObjC work together 
NSBundle* mainBundle = [NSBundle mainBundle]; 
NSString* dll = [mainBundle pathForResource:@"your-dll" ofType:@"dll"]; 

// load the referenced assembly in our domain 
MonoAssembly* assembly = mono_domain_assembly_open(domain, [dll UTF8String]); 
MonoImage* image = mono_assembly_get_image(assembly); 

// find the class we want to wrap and create an uninitialized instance 
MonoClass* classHandle = mono_class_from_name(image, "Name.Space", "YourClass"); 
MonoObject* object = mono_object_new(domain, classHandle); 

// this calls the default, argument-less ctor 
// for more complex constructors, you need to find the method handle and call it 
// (helpful hint: constructors are internally called ".ctor", so the description 
// string will look like "Namespace.Class..ctor()") 
mono_runtime_object_init(object); 

// get a method handle to whatever you like 
const char* descAsString = "Your.NameSpace.YourClass:YourMethod()"; 
MonoMethodDesc* description = mono_method_desc_new(descAsString); 
MonoMethod* method = mono_method_desc_search_in_class(description, classHandle); 

// call it 
void* args[0]; 
mono_runtime_invoke(method, object, args, NULL); 

// when you're done, shutdown the runtime by destroying the app domain 
mono_jit_cleanup(domain); 

:

यह वास्तव में ऊपर दस्तावेज़ के एक वास्तविक पढ़ने को प्रतिस्थापित करना चाहिए नहीं है, लेकिन निम्नलिखित एक गाइड के रूप में देखा जा सकता के रूप में क्या उम्मीद करने के लिए आप MonoMac पर गौर है, जो एपीआई के एक बड़े हिस्से आप एक मैक आवेदन (कोको, CoreImage, CoreAnimation, आदि) में उपयोग कर सकते हैं करने के लिए नेट बाइंडिंग प्रदान करता है के रूप में आप उल्लेख किया है, दूसरी तरह के आसपास जाने के लिए चाहते हो सकता है, और और अपने स्वयं के बाइंडिंग बनाने का मतलब है।

+0

धन्यवाद। यह एक संभावित तरीके की तरह लगता है। लेकिन यह नहीं सरल :( –

+2

@Filip Kunc हाँ, मैं जानता हूँ कि एक तरफ होने से काफी वर्बोज़ है। लोग हमेशा C++/CLI से अधिक शिकायत करते हैं, भले ही यह वास्तव में एक महान कामयाब मिश्रण करने तरीका है और मूल कोड है। फिर भी,, embedding मोनो नहीं है कि बुरा विचार कर उन कॉल के सबसे केवल एक बार (आप पुन: उपयोग किया जाएगा 'MonoDomain',' MonoAssembly', 'MonoImage',' MonoClass' और 'MonoMethod' संभालती है) प्रदर्शन कर रहे हैं। यदि आप एक उच्च के साथ पहले से ही dealth कर दिया है तो स्तरीय भाषा के रनटाइम फ़ंक्शंस (जो एक बड़ा है), यहां कुछ आश्चर्यजनक नहीं है। – zneak

3

यदि आप मैक पर ऐसा कर रहे हैं, तो हाँ, यह संभव है। आईओएस पर इतना नहीं है।

मैक पर, यदि आप मोनोमैक में एक सीएलआई ऐप बना सकते हैं, तो आप एनएसटीस्क का उपयोग करके अपने सीएलआई ऐप को अपने उद्देश्य-सी ऐप से कॉल कर सकते हैं। एनएसटीस्क आपको आसानी से कमांडलाइन उपकरण लॉन्च करने और उसके आउटपुट को कैप्चर करने और इसके साथ बातचीत करने की अनुमति देता है।

NSArray *args = [NSArray arrayWithObjects:@"-arg1", @"-arg2", nil]; 
NSTask *foo = [[NSTask alloc] init]; 
[foo setLaunchPath:@"/usr/bin/foo"]; 
[foo setArguments:args]; 

NSPipe *pipe = [NSPipe pipe]; 
[foo setStandardOutput:pipe]; 

NSFileHandle *output = [pipe fileHandleForReading]; 

[foo launch]; 

NSData *data = [output readDataToEndOfFile]; 

NSString *outputStr = [[NSString alloc] initWithData:data encoding:NSUTF8StringEncoding]; 

NSLog(@"Got stuff: %@", outputStr); 

आमतौर पर, जिस तरह से आप ऐसा करना चाहते हैं, तो आप अपने एप्लिकेशन बंडल के अंदर CLI अनुप्रयोग शामिल है: ऐसा करने के लिए, आप की तरह कुछ करना चाहते हैं। इसके बाद आप NSBundles -pathForResource का उपयोग कर सीएलआई ऐप का मार्ग प्राप्त कर सकते हैं: टाइप प्रकार: विधि।

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

तो, एनएसटीस्क आपके ऐप बंडल में लिपटे बाहरी सीएलआई निष्पादन योग्य का उपयोग करके ऐसा करने का एक तरीका है। दूसरी तरफ, आप सोच रहे होंगे, क्या आप अपने सी # कोड को सीधे उद्देश्य-सी में जोड़ सकते हैं?

अच्छा, उद्देश्य-सी सी का एक सुपरसेट है, और इस तरह, इसमें सी की सभी क्षमताओं हैं। इसके अतिरिक्त, यदि आप उद्देश्य-सी ++ का उपयोग करते हैं तो इसमें सी ++ की सभी क्षमताएं भी हैं। इसलिए, यदि आप या तो सी या सी ++ स्थिर पुस्तकालय उत्पन्न करने के लिए मोनोमैक प्राप्त कर सकते हैं, तो हाँ, आप अपने स्थैतिक पुस्तकालय को अपने उद्देश्य-सी कोको कोड से भी लिंक कर सकते हैं, और यह केवल काम करेगा। मैं आपको बता नहीं सकता कि लाइब्रेरी को मोनोमैक से कैसे बनाना है, लेकिन इसे लिंक करना सिर्फ एक्सकोड में अपनी बिल्ड सेटिंग्स में आपके लिंक किए गए पुस्तकालयों को जोड़ने का मामला है।

संपादित करें: मैं भाषा के रूप में सी ++/सीएलआई से परिचित नहीं हूं, और मैंने सी ++/सीएलआई के अर्थ का अर्थ "सी ++ कमांड लाइन इंटरफेस ऐप" से गलत व्याख्या किया है। उस ने कहा ... मैंने जो तकनीकें वर्णित की हैं, वे अभी भी संभव विधियों के रूप में लागू होती हैं जो आप करना चाहते हैं, लेकिन यह सी ++/सीएलआई इंटरफ़ेस का उपयोग नहीं कर रहा है जैसे आप विंडोज पर कर सकते हैं।