2012-10-11 34 views
6

मैक के लिए मोनो पर DllImport के लिए मूल लाइब्रेरी का पथ सेट करना मैक के लिए मोनो को पोर्ट करने वाला कोड, एक अप्रबंधित C++ लाइब्रेरी में कॉल करता है। मैक पर मैंने अपनी अप्रबंधित लाइब्रेरी को फ्रेमवर्क में पोर्ट किया है (दुर्भाग्य से हमारी बिल्ड प्रक्रिया केवल इसे फ्रेमवर्क के रूप में संकलित करने की अनुमति देती है, न कि एक डाइलिब के रूप में)। मोनो में मैंने अपने प्रोजेक्ट में बिल्ट ऐप के बगल में फ्रेमवर्क फ़ाइल की प्रतिलिपि बनाने के लिए एक पोस्ट बिल्ड चरण स्थापित किया है।मैक

लेकिन जब एक पी/इस डीएल में शामिल होता है तो मुझे एक DllNotFound अपवाद मिलता है। मैंने Mono Interop Wiki के माध्यम से पढ़ा है और ऐसा लगता है कि मोनो पर पी/आमंत्रण केवल DYLD_ * पर्यावरण चर द्वारा इंगित स्थानों पर दिखेगा और वर्तमान निर्देशिका खोज पथ में नहीं है। जब मैंने फ्रेमवर्क को लाइब्रेरी/लाइब्रेरी/फ्रेमवर्क में कॉपी किया, तो मेरे पी/इनवोक कॉल ने ठीक काम किया, लेकिन मैं अपनी फ्रेमवर्क फाइलों को ऐप के बगल में उपस्थित होना पसंद करूंगा और नहीं/लाइब्रेरी/फ्रेमवर्क में।

मैंने किसी भी पी/आमंत्रण कॉल करने से पहले अपने कोड में DYLD_FRAMEWORK_PATH पर्यावरण चर में वर्तमान कार्यशील निर्देशिका को जोड़ने का प्रयास किया, लेकिन सिस्टम। पर्यावरण नामस्थान में मैक के लिए मोनो पर सीमित कार्यक्षमता है और पर्यावरण चर प्राप्त करना या सेट करना समर्थित नहीं है ।

क्या वैसे भी मैं ऐप के बगल में अपनी फ्रेमवर्क फाइलें रख सकता हूं और अभी भी पी/Invoke के लिए abel हो सकता है?

+0

क्या आप कह रहे हैं कि 'सिस्टम। पर्यावरण .etEnvironmentVariable' मोनो में काम नहीं करता है? –

उत्तर

7

चलिए इसे दो प्रश्नों में विभाजित करते हैं: पर्यावरण परिवर्तनीय कैसे सेट करें और मोनोमैक एप्लिकेशन में देशी ढांचे को कैसे बंडल करें।

स्थापना पर्यावरण चर

आपको अपने आवेदन की Info.plist की LSEnvironment खंड में वातावरण चर सेट कर सकते हैं, इस तरह:

<?xml version="1.0" encoding="UTF-8"?> 
    <!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd"> 
    <plist version="1.0"> 
      <dict> 
      <key>CFBundleIdentifier</key> 
      <string>com.yourcompany.TableViewTest</string> 
      <key>CFBundleName</key> 
      <string>TableViewTest2</string> 
      <key>CFBundleVersion</key> 
      <string>1</string> 
      <key>LSMinimumSystemVersion</key> 
      <string>10.6</string> 
      <key>NSMainNibFile</key> 
      <string>MainMenu</string> 
      <key>NSPrincipalClass</key> 
      <string>NSApplication</string> 
      <key>LSEnvironment</key> 
      <dict> 
        <key>Foo</key> 
        <string>Bar</string> 
      </dict> 
    </dict> 
    </plist> 

यह की तरह लगता है मैन्युअल रूप से एक बार उस फ़ाइल को संपादित करने और जोड़ने के लिए करने के लिए कम से कम एक पर्यावरण परिवर्तनीय।

फ़ाइल स्वचालित रूप से मोनो डेवलप द्वारा बनाई गई है, इसलिए आपको केवल LSEnvironment अनुभाग जोड़ना है।

उसके बाद, आप उन्हें मोनो डेवलपमेंट में संपादित कर सकते हैं: प्रोजेक्ट विकल्प, "मैक ओएस एक्स एप्लिकेशन", "उन्नत" पर जाएं।

बंडलिंग मूल निवासी फ़्रेमवर्क एक MonoMac आवेदन में

आप एक देशी ढांचा एक MonoMac आवेदन में बंडल के लिए किसी भी वातावरण चर सेट करने के लिए की जरूरत नहीं है, वहाँ यह करने के लिए एक बहुत आसान है और क्लीनर तरीका है, जो ऑब्जेक्टिव सी

मैंने एक छोटे से test applications को बनाया है, जो एक मूल उद्देश्य सी अनुप्रयोग और एक मोनोमैक में एक ढांचे को बंडल करता है।

पहली चीज़ जो आपको करने की ज़रूरत है वह ऐप के साथ आपके ढांचे को बंडल कर रहा है। वर्तमान में मोनो डेवलपमेंट में इसे स्वचालित रूप से करने का कोई तरीका नहीं है, इसलिए आपको फ़ाइलों को मैन्युअल रूप से कॉपी करने या कुछ पोस्ट-बिल्ड स्क्रिप्ट का उपयोग करने की आवश्यकता है (मेरे उदाहरण में copy-framework.sh देखें)।

मैं फ्रेमवर्क को YourApp.app/Contents/Frameworks/YourFramework.framework में डालने की अनुशंसा करता हूं क्योंकि एक्सकोड इसे कैसे संभालता है; Apple's Documentation भी देखें।

अपने एप्लिकेशन बंडल के अंदर एक लाइब्रेरी का संदर्भ देने के लिए, आप `@executable_path 'का उपयोग कर सकते हैं (dyld man page देखें)।

मैं <dllmap> का उपयोग करके एक app.config फ़ाइल बनाने की अनुशंसा करता हूं, इसलिए आपको अपने कोड में कोई पथनाम डालने की आवश्यकता नहीं है, इस प्रकार फ्रेमवर्क संस्करणों को बदलना आसान हो जाता है। उदाहरण के लिए:

<configuration> 
     <dllmap dll="TestFramework" target="@executable_path/../Frameworks/TestFramework.framework/TestFramework" /> 
    </configuration> 

अपने ढांचे के अंदर वास्तविक पुस्तकालय lib साथ शुरू होता है या .so/.dylib साथ समाप्त होता है, तो आप उस नाम (ऊपर dllmap TestFramework.framework/libTestFramework.dylib दाखिल नहीं होगा, उदाहरण के लिए) का उल्लेख करना होगा है। यह मोनो में एक बग है, जिसे मैंने अभी तय किया है।

+0

यह विधि तब काम करती है जब मैं पर्यावरण चर में अपने ऐप का पूरा पथ देता हूं लेकिन अगर मैं वर्तमान कार्यशील निर्देशिका से संबंधित सापेक्ष पथ देने का प्रयास करता हूं तो विफल रहता है। जब मैंने अपने ऐप में कुछ और डिबगिंग किया तो मैंने पाया कि सीडब्ल्यूडी/पर सेट है। क्या वैसे भी मैं अपने ऐप के रास्ते को हार्डकोड किए बिना पथ दे सकता हूं? – user408410

+0

आप या तो स्टार्टअप फ़ाइल 'YourApp.app/Contents/MacOS/YourApp' को शेल स्क्रिप्ट के साथ प्रतिस्थापित कर सकते हैं या MonoDevelop द्वारा बनाए गए एक को संशोधित कर सकते हैं (https://github.com/mono/monodevelop/blob/master/main/ निर्माण/MacOSX/monostub.m)। हालांकि, मुझे लगता है कि मुझे ऐसा करने का एक बेहतर और साफ तरीका मिल गया है, lemme जल्दी से इसका परीक्षण करें, फिर मैं इसके साथ अपना जवाब अपडेट करूंगा। –

+0

ठीक है, वास्तव में ऐसा करने का एक साफ और आसान तरीका है - इसे काम करने के लिए बस मोनो में एक बग को तुरंत ठीक करने की आवश्यकता है। –

 संबंधित मुद्दे

  • कोई संबंधित समस्या नहीं^_^