มีวิธีใดในการสร้าง. Net library สำหรับ Windows และ Mac โดยอ้างอิงกับแพลตฟอร์ม


12

เรากำลังพยายามพัฒนาแอพข้ามแพลตฟอร์มสำหรับเดสก์ท็อป (Windows และ Mac) โดยใช้ C # แอพนี้มีสิ่งที่ขึ้นอยู่กับแพลตฟอร์มจำนวนมากและหัวหน้าทีมของเราต้องการให้เราเขียนโค้ดนั้นใน C # วิธีง่ายๆในการทำเช่นนี้คือการเขียน wrappers ใน C ++ และเพียงแค่อ้างอิงไลบรารีในโค้ด C # และปล่อยให้ไลบรารี C ++ จัดการกับแพลตฟอร์มสิ่ง ... อนิจจาไม่ควรเป็น

ฉันกำลังพยายามตั้งค่าไลบรารีโดยใช้ Visual Studio สำหรับ Mac ฉันหวังว่าจะสามารถให้อินเทอร์เฟซเดียวในไลบรารีเดียวเพื่อให้เข้าถึงการเข้าถึงข้อความดั้งเดิมไปยังไลบรารีคำพูดบนแพลตฟอร์มปัจจุบัน - ดีกว่าโดยไม่ต้องมีสองแอสเซมบลี ไลบรารีการอ่านออกเสียงข้อความใน C # สำหรับ Windows ไม่สามารถใช้งานได้บน Mac ดังนั้นเราจึงไม่มีตัวเลือกอื่นนอกเหนือจากการให้บริการเชื่อมโยงกับตัวเรา

ฉันมีความสุขที่ได้ให้ห้องสมุดทำการค้นหาระบบปฏิบัติการเพื่อพิจารณาว่าระบบปฏิบัติการใดที่ทำงานอยู่และ / หรือพยายามโหลดไลบรารี่ดั้งเดิมและใช้ไลบรารี่ที่เคยโหลดมาก่อน

ถ้าฉันต้องมีโครงการเดียวที่จะช่วยให้ฉันเขียนการใช้งานสองจะต้องทำ ฉันไม่พบวิธีสร้างโครงการห้องสมุดใน Visual Studio สำหรับ Mac ที่จะอนุญาตให้ทำเช่นนั้น โครงการประเภทเดียวที่จะอนุญาตให้มีการใช้งานหลายครั้งดูเหมือนว่าต้องการการติดตั้งใช้งานสำหรับ iOS หรือ Android


คุณจะใช้ runtime .NET แบบใด
ร่าเริง

2
ซามารินทำสิ่งที่คล้ายกัน อาจจะมีการกำหนดค่าการสร้าง?
Ewan

2
มันน่าสังเกตว่า Visual Studio for mac ไม่ใช่ visual studio จริงๆมันเป็นเพียงสตูดิโอ Xamarin ที่ถูกปรับปรุงใหม่ อาจจะมีบางอย่างในเอกสารของ Xamarin?
richzilla

3
วิธีที่ดีที่สุดคือแอสเซมบลีที่แตกต่างกัน ... หนึ่งสำหรับอินเทอร์เฟซและรหัสทั่วไปและอีกหนึ่งสำหรับแพลตฟอร์มเป้าหมาย อย่างไรก็ตามคุณสามารถกำหนดหลายเป้าหมายและใช้คำสั่ง #if เพื่อสลับการใช้งานได้ ข้อเสียคือไม่มีการประเมินสิ่งที่ไม่ได้เปิดใช้งานเพื่อให้สามารถล้าสมัยได้ง่าย
Berin Loritsch

เมื่อคุณพูดว่าการอ้างอิงขึ้นอยู่กับแพลตฟอร์มคุณกำลังพูดถึงรหัสพื้นเมืองหรือรหัส C # ทั้งหมดหรือไม่
Berin Loritsch

คำตอบ:


4

คุณมีคำถามที่ดี อาจมีการแลกเปลี่ยนกับโซลูชันของคุณ คำตอบที่ดีที่สุดนั้นขึ้นอยู่กับสิ่งที่คุณหมายถึงโดยขึ้นอยู่กับแพลตฟอร์ม ตัวอย่างเช่นหากคุณกำลังเริ่มต้นกระบวนการเพื่อเริ่มแอปพลิเคชันภายนอกและคุณเพียงสลับไปมาระหว่างแอปพลิเคชั่นหนึ่งกับอีกแอปหนึ่งคุณอาจจัดการกับปัญหานั้นได้โดยไม่ยุ่งยากมากเกินไป หากคุณกำลังพูดถึง P / Invoke กับไลบรารี่เนทีฟคุณจะต้องทำสิ่งนั้นให้เสร็จ อย่างไรก็ตามหากคุณกำลังเชื่อมโยงกับไลบรารีที่มีอยู่บนแพลตฟอร์มเดียวเท่านั้นคุณอาจต้องใช้หลายแอสเซมบลี

แอพภายนอก

คุณอาจไม่จำเป็นต้องใช้#ifคำสั่งในสถานการณ์นี้ เพียงตั้งค่าอินเทอร์เฟซและมีการใช้งานหนึ่งรายการต่อแพลตฟอร์ม ใช้โรงงานเพื่อตรวจหาแพลตฟอร์มและจัดหาอินสแตนซ์ที่ถูกต้อง

ในบางกรณีมันเป็นเพียงไบนารีที่คอมไพล์สำหรับแพลตฟอร์มเฉพาะ แต่ชื่อของไฟล์เรียกทำงานและพารามิเตอร์ทั้งหมดจะถูกกำหนดเหมือนกัน ในกรณีนั้นมันเป็นเรื่องของการแก้ไขปฏิบัติการที่ถูกต้อง สำหรับแอปตัวแปลงเสียงจำนวนมากที่สามารถทำงานได้บน Windows และ Linux ฉันมีตัวเริ่มต้นแบบคงที่เพื่อแก้ไขชื่อไบนารี

public class AudioProcessor
{
    private static readonly string AppName = "lame";
    private static readonly string FullAppPath;

    static AudioProcessor()
    {
        var platform = DetectPlatform();
        var architecture = Detect64or32Bits();

        FullAppPath = Path.combine(platform, architecture, AppName);
    }
}

ไม่มีอะไรแฟนซีที่นี่ ชั้นเรียนเฒ่าดีเพียง

P / วิงวอน

P / Invoke ค่อนข้างหลอกลวง บรรทัดล่างคือคุณต้องแน่ใจว่าโหลดไลบรารี่เนทีฟเวอร์ชันที่ถูกต้อง ในหน้าต่างคุณจะ P / เรียกSetDllDirectory()ใช้ แพลตฟอร์มที่ต่างกันอาจไม่ต้องการขั้นตอนนั้น ดังนั้นนี่คือสิ่งที่สามารถยุ่ง คุณอาจต้องใช้#ifคำสั่งเพื่อควบคุมการโทรที่จะใช้ในการควบคุมการแก้ไขเส้นทางห้องสมุดของคุณ - โดยเฉพาะถ้าคุณรวมไว้ในแพ็คเกจการแจกจ่ายของคุณ

การลิงก์ไปยังไลบรารีที่ขึ้นอยู่กับแพลตฟอร์มที่แตกต่างอย่างสิ้นเชิง

แนวทางการกำหนดเป้าหมายหลายโรงเรียนแบบเก่าอาจมีประโยชน์ที่นี่ อย่างไรก็ตามมันมาพร้อมกับความอัปลักษณ์มากมาย ในวันที่บางโครงการพยายามมีเป้าหมาย DLL Silverlight, WPF และ UAP ที่อาจเกิดขึ้นเหมือนกันคุณจะต้องรวบรวมแอปพลิเคชันหลายครั้งด้วยแท็กการรวบรวมที่แตกต่างกัน ความท้าทายของแต่ละแพลตฟอร์มข้างต้นคือแม้ว่าพวกเขาจะแบ่งปันแนวคิดเดียวกัน แต่แพลตฟอร์มนั้นมีความแตกต่างกันมากพอที่คุณต้องหลีกเลี่ยงความแตกต่างเหล่านั้น #ifนี่คือที่เราได้รับในนรกของ

วิธีนี้ยังต้องการการแก้ไข.csprojไฟล์ด้วยมือเพื่อจัดการการอ้างอิงที่ขึ้นกับแพลตฟอร์ม เนื่องจาก.csprojไฟล์ของคุณเป็นไฟล์ MSBuild จึงเป็นไปได้อย่างสิ้นเชิงที่จะทำในลักษณะที่รู้จักและคาดเดาได้

#if นรก

คุณสามารถเปิดและปิดส่วนของรหัสโดยใช้#ifคำสั่งเพื่อให้มีประสิทธิภาพในการจัดการความแตกต่างเล็กน้อยระหว่างแอปพลิเคชัน บนพื้นผิวมันดูเหมือนความคิดที่ดี ฉันยังใช้มันเป็นเครื่องมือในการเปิดและปิดการสร้างภาพกล่องขอบเขตเพื่อดีบักโค้ดการวาด

ปัญหาหมายเลข 1 #ifคือไม่มีรหัสใดที่ปิดใช้งานถูกประเมินโดยตัวแยกวิเคราะห์ คุณอาจมีข้อผิดพลาดทางไวยากรณ์แฝงหรือแย่กว่านั้นคือข้อผิดพลาดเชิงตรรกะที่รอให้คุณคอมไพล์ไลบรารีอีกครั้ง สิ่งนี้จะยิ่งเป็นปัญหากับรหัสการเปลี่ยนโครงสร้างอีกครั้ง บางสิ่งที่ง่ายพอ ๆ กับการเปลี่ยนชื่อเมธอดหรือการเปลี่ยนลำดับของพารามิเตอร์จะจัดการได้ตามปกติ แต่เนื่องจาก parser ไม่เคยประเมินสิ่งใดที่ถูกปิดโดย#ifคำสั่งคุณก็มีรหัสที่แตกหักซึ่งคุณจะไม่เห็นจนกว่าคุณจะคอมไพล์ใหม่

รหัสการดีบักทั้งหมดของฉันที่เขียนในลักษณะนั้นต้องถูกเขียนใหม่หลังจากชุดการรีแฟคเตอร์แตกออกมา ระหว่างการเขียนใหม่ฉันใช้คลาส config ทั่วโลกเพื่อเปิดและปิดคุณสมบัติเหล่านั้น นั่นทำให้การพิสูจน์เครื่องมือ refactor แต่โซลูชั่นดังกล่าวไม่ได้ช่วยเมื่อ API แตกต่างอย่างสิ้นเชิง

วิธีที่ฉันชอบ

วิธีการที่ฉันชอบตามบทเรียนที่เจ็บปวดจำนวนมากที่เรียนรู้และแม้กระทั่งจากตัวอย่างของ Microsoft ก็คือการใช้ชุดประกอบหลายชุด

แอสเซมบลี NetStandard หลักหนึ่งจะกำหนดอินเทอร์เฟซทั้งหมดและประกอบด้วยรหัสทั่วไปทั้งหมด การติดตั้งใช้งานแพลตฟอร์มจะอยู่ในชุดประกอบแยกต่างหากที่จะเพิ่มคุณสมบัติเมื่อรวมอยู่

วิธีการนี้ได้รับการยกตัวอย่างโดย API การกำหนดค่าใหม่และสถาปัตยกรรมเอกลักษณ์ในปัจจุบัน เมื่อคุณต้องการการรวมที่เฉพาะเจาะจงมากขึ้นคุณเพียงแค่เพิ่มการประกอบใหม่เหล่านั้น แอสเซมบลีเหล่านั้นยังมีฟังก์ชันส่วนขยายเพื่อรวมตัวเองเข้ากับการตั้งค่าของคุณ หากคุณใช้วิธีการฉีดแบบพึ่งพาวิธีส่วนขยายเหล่านั้นอนุญาตให้ไลบรารีลงทะเบียนบริการ

นี่เป็นวิธีเดียวที่ฉันรู้เพื่อหลีกเลี่ยง#ifนรกและตอบสนองสภาพแวดล้อมที่แตกต่างกันอย่างมีนัยสำคัญ


ฉันดูดที่ C # (สวรรค์ใช้ C ++ ประมาณ 18 ปีและ C # ประมาณครึ่งวันคาดว่าจะได้) API การกำหนดค่าใหม่นี้ ... คุณช่วยระบุลิงก์ไปยังสิ่งนั้นได้ไหม ฉันดูเหมือนจะไม่พบมันด้วยตัวเอง
ชัดเจน

2
docs.microsoft.com/en-us/aspnet/core/fundamentals/configuration/… มีแพ็คเกจ Nuget หลายชุดเพื่อเพิ่มแหล่งกำหนดค่าเพิ่มเติม ตัวอย่างเช่นจากตัวแปรสภาพแวดล้อมไฟล์ JSON และอื่น ๆ
Berin Loritsch

1
เป็นMicrosoft.Extensions.Configurationชุดของ API
Berin Loritsch

1
นี่คือโครงการ
gitub
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.