সি # সংকলক কীভাবে COM প্রকারগুলি সনাক্ত করতে পারে?


168

সম্পাদনা: আমি ফলাফল একটি ব্লগ পোস্ট হিসাবে লিখেছি ।


সি # সংকলক কিছুটা যাদুকরভাবে COM ধরণের আচরণ করে। উদাহরণস্বরূপ, এই বিবৃতিটি সাধারণ দেখাচ্ছে ...

Word.Application app = new Word.Application();

... যতক্ষণ না আপনি বুঝতে পারছেন যে Applicationএটি একটি ইন্টারফেস। একটি ইন্টারফেসে একটি কনস্ট্রাক্টর কল? Yoiks! এটি আসলে একটি কল Type.GetTypeFromCLSID()এবং অন্যটিতে কল করে অনুবাদিত হয় Activator.CreateInstance

অতিরিক্তভাবে, সি # 4 এ, আপনি refপরামিতিগুলির জন্য অ-রেফার আর্গুমেন্টগুলি ব্যবহার করতে পারেন এবং সংকলক ফলাফলটি বাদ দিয়ে কেবল রেফারেন্স দিয়ে পাস করার জন্য একটি স্থানীয় ভেরিয়েবল যুক্ত করে:

// FileName parameter is *really* a ref parameter
app.ActiveDocument.SaveAs(FileName: "test.doc");

(হ্যাঁ, অনেকগুলি আর্গুমেন্ট অনুপস্থিত রয়েছে optionচ্ছিক পরামিতিগুলি কি সুন্দর নয়? :)

আমি সংকলক আচরণটি তদন্ত করার চেষ্টা করছি এবং আমি প্রথম অংশটি নকল করতে ব্যর্থ হচ্ছি। আমি কোনও সমস্যা ছাড়াই দ্বিতীয় অংশটি করতে পারি:

using System;
using System.Runtime.InteropServices;
using System.Runtime.CompilerServices;

[ComImport, GuidAttribute("00012345-0000-0000-0000-000000000011")]
public interface Dummy
{
    void Foo(ref int x);
}

class Test
{
    static void Main()
    {
        Dummy dummy = null;
        dummy.Foo(10);
    }
}

আমি লিখতে সক্ষম হতে চাই:

Dummy dummy = new Dummy();

যদিও। স্পষ্টতই মৃত্যুদন্ড কার্যকর হওয়ার সময় তা হারাবে, তবে তা ঠিক আছে। আমি শুধু পরীক্ষা নিরীক্ষা করছি।

সংযুক্ত COM পিআইএ জন্য সংকলক দ্বারা যুক্ত অন্যান্য বৈশিষ্ট্যগুলি ( CompilerGeneratedএবং TypeIdentifier) কৌশলটি মনে হচ্ছে না ... যাদু সস কি?


11
Optionচ্ছিক পরামিতিগুলি কি সুন্দর নয়? আইএমও, না তারা সুন্দর নয়। মাইক্রোসফ্ট সি # তে ব্লাট যুক্ত করে অফিস সিওএম ইন্টারফেসের ত্রুটিটি সমাধান করার চেষ্টা করছে।
মেহরদাদ আফশারি

18
@ মেহরদাদ: COচ্ছিক পরামিতি অবশ্যই COM এর বাইরে কার্যকর beyond আপনাকে ডিফল্ট মানগুলি সম্পর্কে সতর্কতা অবলম্বন করা উচিত, তবে তাদের এবং নামযুক্ত তর্কগুলির মধ্যে ব্যবহারযোগ্য পরিবর্তনযোগ্য প্রকার তৈরি করা অনেক সহজ।
জন স্কিটি

1
সত্য। বিশেষত, কিছু গতিশীল পরিবেশের সাথে ইন্টারপ করার জন্য নামযুক্ত প্যারামিটারগুলি ব্যবহারিকভাবে প্রয়োজন হতে পারে । অবশ্যই, কোনও সন্দেহ ছাড়াই এটি একটি দরকারী বৈশিষ্ট্য তবে এর অর্থ এটি নিখরচায় আসে। এটির সরলতা ব্যয় (একটি স্পষ্টভাবে বর্ণিত ডিজাইনের লক্ষ্য)। ব্যক্তিগতভাবে, আমি মনে করি দলটি যে বৈশিষ্ট্যগুলি ছেড়ে গেছে তার জন্য সি # বিস্ময়কর (অন্যথায় এটি সি ++ ক্লোন হতে পারে)। সি # টিম দুর্দান্ত তবে কর্পোরেট পরিবেশ খুব কমই রাজনীতি মুক্ত হতে পারে। আমার ধারণা, এন্ডারস নিজেও এ বিষয়ে খুব খুশি ছিলেন না, যেমন তিনি তাঁর পিডিসি'০৮ বক্তব্যে বলেছেন: "আমরা যেখানে ছিলাম সেখানে ফিরে আসতে দশ বছর সময় নিয়েছিল।"
মেহরদাদ আফশারি

7
আমি একমত যে এই দলের জটিলতার উপর গভীর নজর রাখা দরকার। ডায়নামিক স্টাফ বেশিরভাগ বিকাশকারীদের জন্য স্বল্পমূল্যের জন্য অনেক জটিলতা যুক্ত করে তবে কিছু বিকাশকারীদের জন্য উচ্চ মান ।
জন স্কিটি

1
আমি কাঠামো বিকাশকারীদের অনেক জায়গায় এর ব্যবহারগুলি নিয়ে আলোচনা শুরু করতে দেখেছি। আইএমও এটি ঠিক সময় না পাওয়া পর্যন্ত আমরা এর জন্য খুব ভাল ব্যবহার খুঁজে পাই না dynamic... আমরা কেন স্থির / দৃ outside় টাইপিংয়ের অভ্যর্থনা করছি কেন এটি COM এর বাইরে গুরুত্বপূর্ণ।
চক্রত

উত্তর:


145

কোনও উপায়েই আমি এতে বিশেষজ্ঞ নই, তবে আপনি কী চান তা নিয়ে আমি সম্প্রতি হোঁচট খেয়েছি : কোক্লাস অ্যাট্রিবিউট শ্রেণি।

[System.Runtime.InteropServices.CoClass(typeof(Test))]
public interface Dummy { }

একটি কক্লাস এক বা একাধিক ইন্টারফেসের কংক্রিট প্রয়োগকরণ (গুলি) সরবরাহ করে। সিওএম-তে, এই ধরনের কংক্রিট বাস্তবায়ন যে কোনও প্রোগ্রামিং ভাষায় লিখিত যেতে পারে যা সিওএম উপাদান বিকাশকে সমর্থন করে, যেমন ডেলফি, সি ++, ভিজ্যুয়াল বেসিক ইত্যাদি supports

মাইক্রোসফ্ট স্পিচ এপিআই সম্পর্কে অনুরূপ প্রশ্নের আমার উত্তরটি দেখুন , যেখানে আপনি ইন্টারফেসটি "ইনস্ট্যান্টিয়েট" করতে সক্ষম হলেন SpVoice(তবে সত্যই, আপনি ইনস্ট্যান্ট করছেন SPVoiceClass) ating

[CoClass(typeof(SpVoiceClass))]
public interface SpVoice : ISpeechVoice, _ISpeechVoiceEvents_Event { }

2
খুব আকর্ষণীয় - এটি পরে চেষ্টা করবে। লিঙ্কযুক্ত পিআইএ প্রকারের যদিও কোক্লাস নেই। লিঙ্কিংয়ের প্রক্রিয়াটির সাথে এটি করার কিছু হতে পারে - আমি আসল পিআইএতে একবার নজর রাখব ...
জন স্কিটি

64
এরিক লিপার্ট এবং জন স্কিটি যখন উত্তরও দিয়েছিল তখন স্বীকৃত উত্তর লিখে অসাধারণ হওয়ার জন্য +1;) না, সত্যিই, কোক্লাসের উল্লেখ করার জন্য +1।
অরেগনহোস্ট

61

আপনার এবং মাইকেল এর মধ্যে আপনি প্রায় একসাথে টুকরো টুকরো পেয়েছেন। আমি মনে করি এটি এইভাবে কাজ করে। (আমি কোডটি লিখিনি, তাই আমি এটিকে কিছুটা ভুল করে বলছি, তবে আমি নিশ্চিত যে এটি এভাবেই চলছে))

এমন:

  • আপনি একটি ইন্টারফেস টাইপ "নতুন" করছেন, এবং
  • ইন্টারফেস টাইপ একটি পরিচিত coclass আছে, এবং
  • আপনি এই ইন্টারফেসের জন্য "নো পিয়া" বৈশিষ্ট্যটি ব্যবহার করছেন

তারপরে কোডটি (আইপিআইআইএনআরএন্টারফ্যাক) অ্যাক্টিভেটর হিসাবে তৈরি করা হয়েছে।

এমন:

  • আপনি একটি ইন্টারফেস টাইপ "নতুন" করছেন, এবং
  • ইন্টারফেস টাইপ একটি পরিচিত coclass আছে, এবং
  • আপনি এই ইন্টারফেসের জন্য "নো পিয়া" বৈশিষ্ট্যটি ব্যবহার করছেন না

তারপরে কোডটি এমনভাবে তৈরি করা হয়েছে যেন আপনি "নতুন COCLASSTYPE ()" বলেছিলেন।

জন, এই জিনিস সম্পর্কে আপনার যদি প্রশ্ন থাকে তবে নির্দ্বিধায় আমাকে বা স্যামকে বাগ করুন। এফওয়াইআই, স্যাম এই বৈশিষ্ট্যটির বিশেষজ্ঞ।


36

ঠিক আছে, এটি মাইকেল এর উত্তরে কিছুটা আরও মাংস দেওয়ার জন্য (তিনি চাইলে এটি যুক্ত করতে স্বাগত জানায়, যে ক্ষেত্রে আমি এইটিকে সরিয়ে দেব)।

ওয়ার্ডের জন্য মূল পিআইএটি দেখুন lic আবেদন

[ComImport, TypeLibType(...), Guid("..."), DefaultMember("Name")]
public interface _Application
{
     ...
}

[ComImport, Guid("..."), CoClass(typeof(ApplicationClass))]
public interface Application : _Application
{
}

[ComImport, ClassInterface(...), ComSourceInterfaces("..."), Guid("..."), 
 TypeLibType((short) 2), DefaultMember("Name")]
public class ApplicationClass : _Application, Application
{
}

দুটি কারণে ইন্টারফেস রয়েছে যে কারণে এরিক লিপার্ট আরেকটি উত্তরে কথা বলেছেন । এবং সেখানে, যেমন আপনি বলেছিলেন, CoClassউভয়ই - শ্রেণি নিজেই এবং Applicationইন্টারফেসের বৈশিষ্ট্যের দিক থেকে ।

এখন যদি আমরা পিআইএ সি # 4 লিঙ্ক ব্যবহার করেন, কিছু এই ফলে বাইনারি এমবেড করা হয় ... কিন্তু এটা সব নয়। একটি অ্যাপ্লিকেশন যা এই ধরণের সাথে সবেমাত্র একটি উদাহরণ তৈরি করে Application:

[ComImport, TypeIdentifier, Guid("..."), CompilerGenerated]
public interface _Application

[ComImport, Guid("..."), CompilerGenerated, TypeIdentifier]
public interface Application : _Application

না ApplicationClass- সম্ভবতঃ কারণ বাস্তবায়নের সময় আসল সিওএম টাইপ থেকে এটি গতিশীলভাবে লোড হবে ।

আরেকটি আকর্ষণীয় বিষয় হ'ল সংযুক্ত সংস্করণ এবং নন-লিঙ্কযুক্ত সংস্করণের মধ্যে কোডের পার্থক্য। আপনি যদি লাইনটি নিষ্পত্তি করেন

Word.Application application = new Word.Application();

মধ্যে রেফারেন্সড সংস্করণ হিসাবে এটি শেষ পর্যন্ত:

Application application = new ApplicationClass();

যেহেতু লিঙ্ক সংস্করণ হিসাবে এটি শেষ পর্যন্ত

Application application = (Application) 
    Activator.CreateInstance(Type.GetTypeFromCLSID(new Guid("...")));

সুতরাং এটি দেখে মনে হচ্ছে "বাস্তব" পিআইএ প্রয়োজন CoClassগুণ, কিন্তু কারণ সেখানে লিঙ্ক সংস্করণ না নয় একটি CoClassকম্পাইলার আসলে উল্লেখ করতে পারেন। এটি গতিশীলভাবে করতে হবে।

আমি এই তথ্যটি ব্যবহার করে একটি সিওএম ইন্টারফেস নকল করার চেষ্টা করতে পারি এবং এটি সংযোগ করার জন্য আমি সংকলকটি পেতে পারি কিনা তা দেখতে ...


27

মাইকেল এর উত্তরে কিছুটা নিশ্চিতকরণ যোগ করতে:

নিম্নলিখিত কোডগুলি সংকলন করে এবং রান করে:

public class Program
{
    public class Foo : IFoo
    {
    }

    [Guid("00000000-0000-0000-0000-000000000000")]
    [CoClass(typeof(Foo))]
    [ComImport]
    public interface IFoo
    {
    }

    static void Main(string[] args)
    {
        IFoo foo = new IFoo();
    }
}

এটির কাজ করার জন্য আপনার ComImportAttributeএবং উভয়ই প্রয়োজন GuidAttribute

আপনি যখন মাউসটি new IFoo()মাউভারের উপরে রাখেন তখন সেই তথ্যটিও নোট করুন : বুদ্ধিমানভাবে তথ্যটি সঠিকভাবে তুলে ধরে: দুর্দান্ত!


ধন্যবাদ, আমি চেষ্টা করছিলাম কিন্তু আমি ComImport বৈশিষ্ট্যটি অনুপস্থিত ছিল , কিন্তু আমি যখন সোর্স কোডে যাই তখন আমি F12 ব্যবহার করে কাজ করছিলাম কেবল কোক্লাস এবং গাইড দেখায় , তা কেন?
এহসান সাজ্জাদ
আমাদের সাইট ব্যবহার করে, আপনি স্বীকার করেছেন যে আপনি আমাদের কুকি নীতি এবং গোপনীয়তা নীতিটি পড়েছেন এবং বুঝতে পেরেছেন ।
Licensed under cc by-sa 3.0 with attribution required.