ฉันจะรวบรวมโค้ด C++/CLI สำหรับ Silverlight ได้อย่างไร

ฉันมีไลบรารี C++/CLI ที่ฉันต้องการใช้ในแอปพลิเคชัน Silverlight ควรจะเป็นไปได้ที่จะเขียนโค้ดสำหรับ Silverlight ในภาษา .NET ใดก็ได้ แต่จนถึงตอนนี้ฉันเพิ่งหาวิธีคอมไพล์ C# เท่านั้น ดูเหมือนว่า Silverlight จะไม่สามารถใช้ DLL ที่คอมไพล์สำหรับ .NET ได้

ฉันใช้ Visual Studio 2010 และ Silverlight 4 โปรเจ็กต์ใหม่เดียวที่มีให้สำหรับ Silverlight คือโปรเจ็กต์ C# การย้ายโค้ดไปยัง C# ไม่ใช่ตัวเลือกที่ใช้งานได้จริง

ฉันจะรวบรวมโค้ด C++/CLI สำหรับ Silverlight ได้อย่างไร


comment
C++/CLI ของคุณคอมไพล์ด้วย /clr:safe หรือไม่   -  person Ben Voigt    schedule 20.11.2010


คำตอบ (5)


ฉันคิดว่าฉันอาจได้รับโปรเจ็กต์ไลบรารีคลาส VS2010 C++/CLI เพื่อสร้างโดยมีการอ้างอิงถึงแอสเซมบลี Silverlight (เท่านั้น)

อัปเดต

โอเค เป็นไปได้ เป็นไปได้ แต่มันไม่ดี

ขั้นแรก คุณต้องโน้มน้าวให้คอมไพเลอร์ C++ ไม่โหลด .NET Framework โดยใช้สวิตช์คอมไพเลอร์ที่ไม่มีเอกสาร แต่นั่นไม่ใช่ส่วนที่แย่ที่สุด

  • ตั้งค่าโปรเจ็กต์ C++/CLI ของคุณ "Common Language Runtime Support" เป็น /clr:safe
  • ถัดไป ภายใต้การอ้างอิง ลบการอ้างอิง ทั้งหมด
  • ถัดไป ในคุณสมบัติโปรเจ็กต์ C++/CLI ภายใต้ C++ > Command Line ให้ป้อน /d1clr:nomscorlib /FU"C:\Program Files (x86)\Microsoft Silverlight\4.0.50917.0\mscorlib.dll"
  • ตอนนี้ บันทึกโครงการ และออกจาก Visual Studio เปิด .vcxproj ในโปรแกรมแก้ไขข้อความ และเปลี่ยนการตั้งค่าเวอร์ชันของเฟรมเวิร์ก คุณต้องการให้เหมือนกับโปรเจ็กต์ C# Silverlight:

    <TargetFrameworkIdentifier>Silverlight</TargetFrameworkIdentifier> <TargetFrameworkVersion>v4.0</TargetFrameworkVersion> <SilverlightVersion>$(TargetFrameworkVersion)</SilverlightVersion>

  • ตอนนี้ เปิด Visual Studio อีกครั้ง และสร้างโครงการ คุณจะได้รับข้อผิดพลาดเนื่องจากคอมไพเลอร์สร้างไฟล์ที่มี #using<mscorlib> โดยอัตโนมัติ และพาธการค้นหาจะค้นหาเวอร์ชัน .NET Framework ก่อน

    Silverlight,Version=v4.0.AssemblyAttributes.cpp(1): fatal error C1197: cannot reference 'c:\windows\microsoft.net\framework\v4.0.30319\mscorlib.dll' as the program has already referenced 'c:\program files (x86)\microsoft silverlight\4.0.50917.0\mscorlib.dll'

  • ดับเบิลคลิกที่ข้อผิดพลาดเพื่อเปิดไฟล์ที่สร้างขึ้นอัตโนมัติ แทนที่การอ้างอิงแบบไม่มีเส้นทางด้วยเช่น (นี่คือที่ที่คุณใส่ข้อมูลอ้างอิง ไม่ใช่ในคุณสมบัติของโครงการ)

    #using <c:\program files (x86)\microsoft silverlight\4.0.50917.0\mscorlib.dll>

    #using <c:\program files (x86)\microsoft silverlight\4.0.50917.0\System.dll>

    #using <c:\program files (x86)\microsoft silverlight\4.0.50917.0\System.Core.dll>

  • โชคดีที่คอมไพเลอร์ปล่อยให้การเปลี่ยนแปลงของคุณอยู่กับที่ ดังนั้นคุณควรจะทำได้ดีตราบใดที่ไม่มีใครล้างไดเร็กทอรีชั่วคราวของคุณ

  • ตอนนี้การสร้างควรจะสำเร็จแล้ว

จากนั้น คุณต้องเพิ่ม DLL ที่สร้างโดยโปรเจ็กต์ C++/CLI ไปยังแอปพลิเคชัน Silverlight ของคุณ โปรดทราบว่าคุณไม่สามารถตั้งค่าการอ้างอิงโปรเจ็กต์ได้ เนื่องจาก VS2010 ยังไม่มั่นใจว่า C++/CLI นั้นเป็นโปรเจ็กต์ Silverlight ดังนั้นคุณจะต้องเรียกดูและเพิ่มข้อมูลอ้างอิงเป็นไฟล์แอสเซมบลี (และจะไม่สลับระหว่าง Debug และ Release โดยอัตโนมัติเพื่อให้ตรงกับแอปพลิเคชัน Silverlight)

หมายเหตุสุดท้าย

ฉันได้รับมันเพื่อเรียกใช้แอปพลิเคชัน Silverlight ที่ว่างเปล่าในโหมด Debug และหยุดที่เบรกพอยต์ตรงกลางของโค้ด C++/CLI นอกจากนี้โค้ด C++/CLI ส่งคืนค่าให้กับ C# ได้สำเร็จ และตัวแปรโลคัลใน C# ก็ได้รับค่าที่ถูกต้อง ดังนั้นฉันเดาว่ามันได้ผล

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

person Ben Voigt    schedule 20.11.2010
comment
เห็นได้ชัดว่าจำเป็นต้องมีส่วนประกอบ Visual Web Developer... ฉันจะกลับมาในภายหลัง (ในภายหลังมาก) - person Ben Voigt; 21.11.2010
comment
SDK อยู่ที่นี่: microsoft .com/downloads/en/ - person richj; 21.11.2010
comment
ฉันต้องทำการติดตั้งคุณสมบัติบน VS2010 เอง จากนั้นเพิ่ม microsoft.com/downloads/en/ จากนั้นเพิ่ม Developer Runtime เมื่อได้รับแจ้งจาก VS - person Ben Voigt; 21.11.2010
comment
ขอบคุณมากสำหรับคำตอบของคุณ. ฉันไม่ได้เจออะไรแบบนี้อีกเลยในการค้นหาเว็บหลายชั่วโมง - person richj; 22.11.2010
comment
@richj: ฉันไม่พบว่าคอมไพเลอร์เปลี่ยนตัวเอง ดู opensubscriber.com/message/dotnet-cx@discuss .develop.com/ แต่เธรดนั้นไม่ได้แสดงวิธีใช้งานจริง ฉันต้องยุ่งกับตัวเลือกต่างๆ มากมายเพื่อให้สามารถคอมไพล์ได้สำเร็จ และเมื่อไฟล์หนึ่งถูกคอมไพล์ในที่สุด ฉันพบปัญหานั้นกับไฟล์ที่สร้างขึ้นอัตโนมัติ คุณได้รับมันเพื่อทำงานกับรหัสของคุณหรือไม่? - person Ben Voigt; 23.11.2010
comment
ขั้นตอนเหล่านี้จะใช้ได้กับ VS2012/.NET 4.5/SL 5 เพียงเปลี่ยนพาธและแอตทริบิวต์ .vcxproj ตามต้องการ นอกจากนี้ 2012 จะอนุญาตให้คุณเพิ่ม CPP DLL เป็นข้อมูลอ้างอิงโครงการโดยตรงได้ ฉันได้ติดตั้งชุดเครื่องมือ SL และ VC++ ที่สามารถแจกจ่ายต่อได้ก่อนที่จะลองทำสิ่งนี้ ฉันไม่จำเป็นต้องทำการติดตั้งใดๆ เพื่อสร้างโปรเจ็กต์และอ้างอิงได้สำเร็จ - person Esoteric Screen Name; 28.10.2013

Ben Voigt ขอบคุณสำหรับสิ่งนี้ มันก็ได้ผลสำหรับฉันเช่นกัน

นอกจากนี้ หากโค้ด C++ ของคุณทำอะไรก็ตามที่เฉพาะเจาะจงกับภาษา C++ (กล่าวคือ ไม่ใช่ IL แบบพกพาทั้งหมด) เช่น การใช้สแต็กซีแมนทิกส์สำหรับอาร์เรย์ คุณจะได้รับข้อผิดพลาดต่อไปนี้:

could not find assembly 'Microsoft.VisualC.dll' etc.

หากคุณคอมไพล์ใหม่ด้วย .NET Framework แบบเต็ม แล้วดัมพ์โค้ด IL คุณจะพบการอ้างอิงถึง "''.$ArrayType$$$BY06$$CB_W modopt" หรืออะไรที่คล้ายกัน สิ่งนี้จะบอกคุณว่าต้องเปลี่ยนรหัสที่ไหน

ฉันพบว่าหลังจากที่ฉันติดตั้ง Silverlight SDK และเพิ่มลงใน "\Program Files(x86)\Reference Assemblies" ฉันไม่จำเป็นต้องทำตามขั้นตอนทั้งหมดของ Ben Voigt แค่เปลี่ยนไฟล์โปรเจ็กต์ก็เพียงพอแล้ว

หมายเหตุอีกประการหนึ่ง คุณยังสามารถใช้:

<TargetFrameworkProfile>WindowsPhone71</TargetFrameworkProfile>

หากคุณต้องการกำหนดเป้าหมาย Windows Phone (ติดตั้ง SDK ก่อน)

person Don Fehr    schedule 07.12.2011

Silverlight ไม่รองรับไลบรารี C++ ดั้งเดิม หรือสถานการณ์ P/Inrigg ใดๆ เนื่องจากข้อกังวลด้านความปลอดภัย หากไลบรารี่ของคุณเป็น .Net ล้วนๆ คุณอาจสามารถถอดรหัสมันด้วย ILDASM และคอมไพล์ใหม่สำหรับ Silverlight ด้วย ILASM ได้

person Joel Lucsy    schedule 20.11.2010
comment
ขอบคุณ จากสิ่งที่ฉันได้อ่านมา รหัส .NET MSIL บางรหัสอาจทำให้เกิดปัญหากับรันไทม์ของ Silverlight ได้ มันอาจจะคุ้มค่าที่จะลอง - ฉันจะต้องตรวจสอบความครอบคลุมของการทดสอบหน่วยสำหรับห้องสมุด - person richj; 20.11.2010

Silverlight ไม่ใช่แพลตฟอร์มการพัฒนาที่ทรงพลังเช่น .NET ซึ่งรวมเข้ากับระบบปฏิบัติการอย่างแน่นหนา ก่อนอื่น Silverlight ควรทำงานบนระบบปฏิบัติการใดๆ ก็ตาม ดังนั้นจึงไม่มีตัวเลือก Native API ในทุกที่ใน Silverlight

Silverlight ยังไม่รองรับ MSIL อย่างสมบูรณ์ ดังนั้นจึงมีปัญหามากมายในการคอมไพล์และคอมไพล์ใหม่ในระดับ IL

คุณช่วยพูดเพิ่มเติมเกี่ยวกับรหัส C++/CLI ที่คุณมีได้ไหม? แอปพลิเคชันอินเทอร์เน็ตที่สมบูรณ์ที่สุด (เป้าหมายของ Silverlight) ไม่มีการคำนวณที่ทรงพลังใดๆ เลย แต่เป็นทางเลือก HTML+JS ธรรมดาๆ แทน หากต้องการกราฟิกที่ทรงพลัง คุณสามารถใช้การรองรับ PixelShadder ของ Silverlight

ตัวสะท้อนแสง

สิ่งที่คุณสามารถทำได้คือ คอมไพล์ C++/CLI ของคุณเป็น .NET DLL ปกติ ใช้ Reflector เพื่อแยกส่วนและสร้างซอร์สโค้ด C# จาก dll ของคุณ มันอาจจะไม่สมบูรณ์แบบ แต่ตรรกะส่วนใหญ่ของคุณจะถูกแปลงกลับเป็น C#

person Akash Kava    schedule 20.11.2010
comment
รหัส C++/CLI เป็นรหัสที่ได้รับการจัดการจาก .NET ล้วนๆ ไม่มีส่วนต่อประสานกับผู้ใช้หรือกราฟิก มันเป็นเพียงไลบรารี่ตรงที่มีการขึ้นต่อกันน้อยมาก ยกเว้น DLL ระดับระบบที่ควรมีใน Silverlight ด้วย - person richj; 20.11.2010
comment
@richj: ตาม DLL ระดับระบบคุณหมายถึงแอสเซมบลี. NET จริง ๆ ซึ่งรวมอยู่ในแพลตฟอร์ม Silverlight หรือไม่ - person Ben Voigt; 20.11.2010
comment
@Ben: ใช่ - แอสเซมบลีที่เป็นของแพลตฟอร์ม Silverlight - person richj; 20.11.2010
comment
ในการทำงานในสภาพแวดล้อมของฉัน Reflector จะต้องแปลจาก C++/CLI เป็น C# ได้อย่างน่าเชื่อถือในกระบวนการสร้างอัตโนมัติเต็มรูปแบบ ฉันไม่สามารถย้ายได้เพียงครั้งเดียวเนื่องจากห้องสมุดอยู่ระหว่างการพัฒนา ฉันจะลองดูถ้าฉันถึงทางตันด้วยวิธีของ Ben Voigt ขอบคุณ - person richj; 22.11.2010

ฉันสามารถแก้ไขปัญหาของ Ben Voigt ในการทำงานกับการเปลี่ยนแปลงเล็กน้อยใน Visual Studio 2013 นี่คือสิ่งที่ฉันทำแตกต่างออกไป

  • ยกเลิกการโหลดโปรเจ็กต์ Silverlight ที่คุณต้องการอ้างอิง คลิกขวาและเลือกแก้ไข project.csproj
  • #P2#
    <TargetFrameworkIdentifier>Silverlight</TargetFrameworkIdentifier>
    <TargetFrameworkVersion>v5.0</TargetFrameworkVersion>
    <SilverlightVersion>$(TargetFrameworkVersion)</SilverlightVersion>
    
  • สำหรับสวิตช์คอมไพเลอร์ /d1clr:nomscorlib นี่ใช้ไม่ได้สำหรับฉัน นอกจากนี้ การอ้างอิงถึง mscorlib สำหรับ Silverlight ยังถูกเพิ่มไปยังเอาต์พุตที่ปฏิบัติตามโดยอัตโนมัติ โดยไม่ต้องระบุในตัวเลือกบรรทัดคำสั่ง นี่คือวิธีที่ฉันได้รับมัน

  • เปิดโครงการใน Just Deompile

  • โหลดปลั๊กอินตัวแก้ไขแอสเซมบลี

  • นำทางต้นไม้ไปยังข้อมูลอ้างอิง

  • ลบการอ้างอิงถึง mscorlib ที่ไม่ใช่ silverlight ออกจากเมนูสะท้อนกลับ

  • คลิกขวาที่ระดับบนสุดของแผนผังสำหรับแอสเซมบลี และบันทึกใต้เมนูสะท้อนกลับ

ฉันยังไม่ได้ทดสอบฟังก์ชั่นทั้งหมด แต่ฟังก์ชั่นที่ฉันทดสอบจนถึงตอนนี้ทำงานได้ตามที่คาดไว้

ขอบคุณเบน โพสต์ของคุณช่วยฉันประหยัดเวลาได้มาก ฉันคิดว่าจะต้องย้ายห้องสมุดของฉัน :)

person Duane McKinney    schedule 30.01.2014