2011-02-08 4 views
2

カスタムCOMインターフェイス用の.netラッパーを作成しようとしています。マーシャリングChar *。すべての文字を取得する方法

インタフェースがC++で、次のように定義されています

DECLARE_INTERFACE_(IDumpAsf, IUnknown) 
{ 
    STDMETHOD(get_UserParams) (THIS_ 
       int *is_auto_start, 
       int *fileSize,   
       int *packetSize, 
       char *baseName, 
       char *filePath 
      ) PURE; 

    STDMETHOD(set_UserParams) (THIS_ 
       int is_auto_start, 
       int fileSize,   
       int packetSize, 
       char *baseName, 
       char *filePath 
      ) PURE; 

    STDMETHOD(enable_Run) (THIS_ 
       bool is_run 
      ) PURE; 
}; 

そして、私はC#で、このようなインターフェースを宣言している:

public interface IDumpASF 
{ 

    [PreserveSig] 
    int get_UserParams(
     [Out] out int is_auto_start, 
     [Out] out int fileSize, 
     [Out] out int packetSize, 
     [Out] out System.Sbyte baseName, 
     [Out] out System.SByte filePath 
     ); 

    [PreserveSig] 
    int set_UserParams(
     [In] int is_auto_start, 
     [In] int fileSize, 
     [In] int packetSize, 
     [In] string baseName, 
     [In] string filePath 
     ); 

    [PreserveSig] 
    int enable_Run([In] bool a); 

} 

使用のexsampleはこれです:

int is_auto_start; 
int fileSize; 
int packetSize; 
SByte baseName; 
SByte filePath; 

IDumpASF dump = (IDumpASF)asfWriter; 

dump.get_UserParams(out is_auto_start, out fileSize, out packetSize, out baseName, out filePath); 

私は魂を構築して実行することができますが、私はどのようにすべての文字を取得すると思いますかbaseNameおよびfilePath SByteを送ると、最初のキャラクターが戻ってきますが、残りはどうすればいいですか?私はSbyte []、String、StringBuilder、IntPtrのようないくつかのタイプを試しました。文字列に変換しようとするたびに、私はAccessViolationExceptionを取得します。

私が逃したばかげたことがあると思うが、私の患者はここで薄くなっている。

どのようなヘルプが多くのappriciatedでしょう!

-Svein

答えて

2

あなたがからを使用していない、StringBuilderのように引数を宣言しなければなりません。正しく渡した文字列ビルダーを初期化してください。このネイティブコードでガベージコレクションされたヒープを破棄できないように、Capacityを十分に高く設定する必要があります。 COMコードを修正することは、基本的に安全ではないので、実際にBSTRを使用する必要があるため、検討する必要があります。

+0

こんにちはハンス。説明したように、私はこれにStringBuilderを使用することができます。私もSByteの配列でテストを行いました.MarshalAs(UnmanagedType.LPArray)を使用するとうまくいきます。何が奨励されているかに関する提案はありますか? – Svein

+0

@Svein、StringBuilderは標準的な方法です。 Encoding.Default.GetString()を使用してbyte []から文字列に変換する必要がなくなります。 –

+0

Ok。私はStringBuilderに行くでしょう。ありがとう。 – Svein

0

ありがとうございます。いくつかの試行錯誤の末、私は最終的に正しいセットアップを得ました。あなたが言ったように、私は[アウト]なしでStringBuilderを使用する必要があります。私の問題は、私が得た価値はあまり意味がないということでした。あなたが私に言ったことに加えて、MarshalAs属性で値をマーシャリングする方法も指定しなければなりませんでした。

ありがとうございました!

これはテストクラスは次のようになります。

System.Text.StringBuilder baseName = new System.Text.StringBuilder(256); 
System.Text.StringBuilder filePath = new System.Text.StringBuilder(256); 

EncirisWrapper.IDumpASF dump = (EncirisWrapper.IDumpASF)asfWriter; 

dump.get_UserParams(out is_auto_start, out fileSize, out packetSize, baseName, filePath); 

そして、これは、ラッパーがどのように見えるかです:

[PreserveSig] 
int get_UserParams(
    [Out] out int is_auto_start, 
    [Out] out int fileSize, 
    [Out] out int packetSize, 
    [MarshalAs(UnmanagedType.LPStr)] System.Text.StringBuilder baseName, 
    [MarshalAs(UnmanagedType.LPStr)] System.Text.StringBuilder filePath  
    ); 

-Svein

関連する問題