質問

次のように定義されたネイティブDLLに関数があります:

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

これをMicrosoftのP / Invoke Interop Assistantに入れようとしましたが、&quot; string&quot;クラス(MFCからですか?)。

さまざまなタイプ(C#String、char []、byte [])としてマーシャリングしようとしましたが、NotSupportedExceptionまたはNative Assembly Exceptionを受け取るたびに(試したマーシャリングに応じて)。

ネイティブ文字列クラスが使用されるネイティブ/マネージド相互運用を行ったことがありますか?これを元sにする方法はありますか?独自のマーシャラーを作成する必要がありますか?

役に立ちましたか?

解決

C ++標準ライブラリ文字列クラスを使用しようとしているようです。それは元Marに簡単だとは思わない。文字*とMarshalをStringBuilderとして使用することをお勧めします。それは私が通常行うことです。 C ++文字列を生成するラッパーを追加する必要があります。

他のヒント

PInvoke相互運用アシスタントは、C ++ではなくCのみをサポートします。残念ながら、MFC Stringクラス(CStringは信じますか?)はC ++であり、アシスタントでは機能しません。代わりに、次を使用してみてください

void SetPath(__in const WCHAR* path);

はい。あなたはできる。実際、 std :: string std :: wstring だけでなく、標準のC ++クラスまたは独自のクラスをマーシャリングまたはインスタンス化して、C#/。NETから呼び出すことができます

.NETワールドからC ++オブジェクトをインスタンス化する基本的な考え方は、.NETからC ++オブジェクトの正確なサイズを割り当て、C ++ DLLからエクスポートされたコンストラクターを呼び出してオブジェクトを初期化することです。関数のいずれかを呼び出してそのC ++オブジェクトにアクセスします。メソッドのいずれかが他のC ++クラスを含む場合、それらをC#クラスでラップする必要があります。プリミティブ型のメソッドの場合は、単純にP / Invokeを実行できます。呼び出すメソッドが数個しかない場合は簡単で、手作業でコーディングするのに時間がかかりません。 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 Interop SDK

(私はSDKツールの作成者です)

C ++クラスのC#ラッパークラスが準備できたら、 ICustomMarshaler を簡単に実装できるため、.NETからC ++オブジェクトをマーシャリングできます。

http://msdn.microsoft.com/ en-us / library / system.runtime.interopservices.icustommarshaler.aspx

ライセンス: CC-BY-SA帰属
所属していません StackOverflow
scroll top