2009-08-08 16 views
0

これは私の2番目の投稿です。アンマネージC++プログラムの構造体をC#プログラムに渡すにはどうすればよいですか?

これは私がやろうとしていることです:C#から管理されていないC++プログラムを呼び出し、C#プログラムから構造体の配列を渡して、C++プログラムから構造体の配列の更新バージョンを返します。ここで

は、呼び出し元のC#のプログラムは次のとおりです。

using System; 
using System.Runtime.InteropServices; 

namespace TestCallingC 
{ 
    class Program 
    { 
     [DllImport(@"..\..\..\Debug\TestCProgram.dll")] 
     public static extern void testfunc(teststruc[] ts); 

     static void Main(string[] args) 
     { 
      teststruc[] teststructs = new teststruc[6]; 
      for (int i = 0; i < teststructs.Length; i++) 
      { 
       teststructs[i].int1 = (i + 1) * 100; 
       teststructs[i].int2 = (i + 1) * 100; 
      } 

      testfunc(teststructs); 
      for (int i = 0; i < teststructs.Length; i++) 
      { 
       Console.WriteLine("Int1 = {0}", teststructs[i].int1); 
       Console.WriteLine("Int2 = {0}", teststructs[i].int2); 
      } 
     } 
    } 

    [StructLayout(LayoutKind.Sequential)] 
    public struct teststruc 
    { 
     [MarshalAs(UnmanagedType.I4)] 
     public int int1; 
     [MarshalAs(UnmanagedType.I4)] 
     public int int2; 
    } 
} 

ここで返すC++プログラムです:

extern "C" __declspec(dllexport) void testfunc (teststruc* ts) 
{ 
    int i; 

    for (i = 0; i < 6; i++) 
    { 

     ts[i].int1 = i; 
     ts[i].int2 = i; 
    } 

    for (i = 0; i < 6; i++) 
    { 
     printf("ts[%d].int1 = %d\n", i, ts[i].int1); 
     printf("ts[%d].int2 = %d\n", i, ts[i].int2); 
    } 

    return; 
} 

は、私は上記のバージョンでは、インバウンド構造体から見ると、印刷するためのC++プログラムすることができますc#プログラムから渡されます。コントロールがc#プログラムに戻されると、データは元の設定と同じになります。これにより、呼び出されたC++プログラムによって構造体が更新されます。ここにコンソール出力があります。最初の部分は、C++プログラムと呼ばれる更新されたフィールドを示しています。第二部は、C# 、発信者によってどのようなWSは、もともと設定されている:私は署名を呼び出すC#のに「REF」タグを追加した場合、構造体が戻ってCから返さ

ts[0].int1 = 0 
ts[0].int2 = 0 
ts[1].int1 = 1 
ts[1].int2 = 1  
ts[2].int1 = 2 
ts[2].int2 = 2  
ts[3].int1 = 3 
ts[3].int2 = 3  
ts[4].int1 = 4 
ts[4].int2 = 4 
ts[5].int1 = 5 
ts[5].int2 = 5 

Int1 = 100 
Int2 = 100 
Int1 = 200 
Int2 = 200 
Int1 = 300 
Int2 = 300 
Int1 = 400 
Int2 = 400 
Int1 = 500 
Int2 = 500 
Int1 = 600 
Int2 = 600 

++プログラムがnullである:

[DllImport(@"..\..\..\Debug\TestCProgram.dll")] 
     public static extern void testfunc(ref teststruc[] ts); 

testfunc(ref teststructs); 

質問:C++プログラムで構造体が正しく更新され、C#プログラムに返されるようにするためには、C++およびc#プログラムのインタフェースの更新が必要ですか?

私は同様のことに関する多くの情報を発見しましたが、それを実現するための正しい組み合わせは何もありませんでした。どんな助言も大歓迎です。

ありがとうございます。 -Greg

+1

この愚かなdownvotingを停止する必要があります。もしあなたが人を誰かに下降させようとしているのであれば、それを行う理由を提供することができます。 –

+1

私はdownvoteをしませんでしたが、これはJim Pulsがそれを編集する前に完全に判読できませんでした。質問のタイトルは「シニアソフトウェアエンジニア」でした。これは、インタビューの質問やテストである可能性があります。 – ChssPly76

+1

「奇妙な」ダウンボックスが表示されている場合は、編集履歴に常に注意する価値があります。時々説明はそこにある... – dmckee

答えて

1

ランダム野生推測:MSDNから

[DllImport(@"..\..\..\Debug\TestCProgram.dll")] 
public static extern void testfunc([In, Out] teststruc[] ts); 

:配列とフォーマット、非blittable型タイプに適用した場合InAttributeOutAttributeを組み合わせる

が特に有用です。呼び出し元は、両方の属性を適用した場合にのみ、これらの型に対して呼び出し先が行う変更を認識します。 [...]

+0

[In、Out]が機能しました。構造体をC++に渡して、C++プログラムから呼び出し元のC#プログラムに更新を返すことができました。 このテクニックをより大きなアプリケーションに適用できます。 もう一度ありがとうございます。このボードは素晴らしいリソースです。 –

+0

うれしい私は助けることができます。あなたの問題を解決するならば、答えを受け入れることを忘れないでください。 :) – dtb

0

最終溶液:

C++(intialバージョンからの変更なし)。

C#コード:

using System; 
using System.Runtime.InteropServices; 

namespace TestCallingC 
{ 
    class Program 
    { 
     [DllImport(@"..\..\..\Debug\TestCProgram.dll")] 
     public static extern void testfunc([In, Out] teststruc[] ts); 

     static void Main(string[] args) 
     { 
      teststruc[] teststructs = new teststruc[6]; 
      for (int i = 0; i < teststructs.Length; i++) 
      { 
       teststructs[i].int1 = (i + 1) * 100; 
       teststructs[i].int2 = (i + 1) * 100; 
      } 

      testfunc(teststructs); 
      for (int i = 0; i < teststructs.Length; i++) 
      { 
       Console.WriteLine("Int1 = {0}", teststructs[i].int1); 
       Console.WriteLine("Int2 = {0}", teststructs[i].int2); 
      } 
     } 
    } 

    [StructLayout(LayoutKind.Sequential)] 
    public struct teststruc 
    { 
     [MarshalAs(UnmanagedType.I4)] 
     public int int1; 
     [MarshalAs(UnmanagedType.I4)] 
     public int int2; 
    } 
} 
関連する問題