سؤال

ولدي وظيفة في DLL الأصلي محددة كما يلي:

#include <string>
void SetPath(string path);

وحاولت أن تضع هذا في مايكروسوفت P / استدعاء إمكانية التشغيل المتداخل مساعد، لكنه يغص بها على الطبقة "السلسلة" (وهو ما أعتقد أنه من MFC؟).

ولقد حاولت التعبئة بأنها مجموعة متنوعة من أنواع مختلفة (C # سلسلة شار [] [] بايت) ولكن في كل مرة كنت إما أن تحصل على NotSupportedException أو استثناء الجمعية الأصلية (اعتمادا على ما التعبئة حاولت).

وكما فعلت كل من أي وقت مضى الأصلية / المدارة إمكانية التشغيل المتداخل حيث يتم استخدام الفئة سلسلة الأصلي؟ هل هناك أي طريقة لحشد هذا؟ أنا ذاهب لدينا لإرسال بلدي منظم؟

هل كانت مفيدة؟

المحلول

ويبدو كما لو كنت تحاول استخدام الطبقة سلسلة المكتبة القياسية C ++. أشك في أنه سيكون من السهل أن المشير. من الأفضل أن العصا مع شار * والمشير كما ب StringBuilder. هذا ما أفعل عادة. سيكون لديك لإضافة المجمع الذي يولد سلسلة من C ++ بالنسبة لك.

نصائح أخرى

ومساعد إمكانية التشغيل المتداخل PInvoke يدعم فقط C ++ لا C. للأسف فئة سلسلة MFC (CString أعتقد؟) هو C ++ ولن تعمل من خلال مساعد. وبدلا من ذلك حاول استخدام التالي

void SetPath(__in const WCHAR* path);

نعم. تستطيع. في الواقع، وليس فقط std::string، std::wstring، أي معيار C ++ فئة أو فئات الخاصة بك يمكن تنظيم أو مثيل، ودعا من C # /. NET.

والفكرة الأساسية لinstantiating الكائن C ++ من العالم. NET هو تخصيص حجم الدقيق للكائن C ++ من .NET، ثم استدعاء منشئ التي يتم تصديرها من C ++ DLL تهيئة الكائن، فإنك سوف تكون قادرة على استدعاء أي من وظائف للوصول إلى C الكائن ++، إذا كان أي من أسلوب ينطوي على الطبقات الأخرى C ++، سوف تحتاج للالتفاف عليها في C # طبقية كذلك، لطرق مع أنواع بدائية، يمكنك ببساطة P / استدعاء لهم. إذا كان لديك فقط عدد قليل من الطرق للاتصال، فإنه سيكون بسيطة، وسوف الترميز اليدوي لا تستغرق وقتا طويلا. عندما كنت فعلت مع كائن C ++، استدعاء الأسلوب المدمر من وجوه C ++، التي هي وظيفة التصدير أيضا. إذا لم يكن لديك واحدة، ثم كنت بحاجة فقط لتحرير الذاكرة من .NET.

وهنا مثال على ذلك.

public class SampleClass : IDisposable
{    
    [DllImport("YourDll.dll", EntryPoint="ConstructorOfYourClass", CharSet=CharSet.Ansi,          CallingConvention=CallingConvention.ThisCall)]
    public extern static void SampleClassConstructor(IntPtr thisObject);

    [DllImport("YourDll.dll", EntryPoint="DoSomething", CharSet=CharSet.Ansi,      CallingConvention=CallingConvention.ThisCall)]
    public extern static void DoSomething(IntPtr thisObject);

    [DllImport("YourDll.dll", EntryPoint="DoSomethingElse", CharSet=CharSet.Ansi,      CallingConvention=CallingConvention.ThisCall)]
    public extern static void DoSomething(IntPtr thisObject, int x);

    IntPtr ptr;

    public SampleClass(int sizeOfYourCppClass)
    {
        this.ptr = Marshal.AllocHGlobal(sizeOfYourCppClass);
        SampleClassConstructor(this.ptr);  
    }

    public void DoSomething()
    {
        DoSomething(this.ptr);
    }

    public void DoSomethingElse(int x)
    {
        DoSomethingElse(this.ptr, x);
    }

    public void Dispose()
    {
        Marshal.FreeHGlobal(this.ptr);
    }
}

لمن التفاصيل، يرجى الاطلاع على الرابط أدناه،

C # /. NET PInvoke إمكانية التشغيل المتداخل SDK

و(أنا مؤلف أداة SDK)

وبمجرد أن يكون لديك C # فئة المجمع الخاص بك C ++ الطبقة جاهزة، فمن السهل لتنفيذ ICustomMarshaler بحيث يمكنك تعبئة كائن C ++ من .NET.

http://msdn.microsoft.com/ أون لنا / مكتبة / system.runtime.interopservices.icustommarshaler.aspx

مرخصة بموجب: CC-BY-SA مع الإسناد
لا تنتمي إلى StackOverflow
scroll top