2009-04-22 40 views
4

構造体へのポインタを返すC関数をC#で宣言するにはどうすればよいですか?p/invoke構造体へのポインタを返すC関数

私はこれを行う方法の1つは、Marshal.PtrToStructureの後に実際の構造値を取得することです。私はそのことについて修正

// C-function 
SimpleStruct * Function(void); 

// C# import 
[DllImport("MyDll.dll")] 
public static extern IntPtr Function(); 
  1. アム?
  2. これを達成する他の方法はありますか? (値で構造体を返すのは問題ありません)

答えて

4

この関数はポインタ(おそらくローカルに割り当てられたものではありません)を返しますので、手動でマージすることをお勧めします(Marshal.PtrToStructure経由)。

パラメータの場合は、PInvoke Interop Assistantを使用して構造の管理バージョンを作成し、refまたはoutを使用して渡すことができます。

+0

ポインタを手動でマーシャリングする必要はほとんどありません。通常、構造体を直接操作することができます。 –

+0

私はあなたが間違っていると信じています。ポインターの手動マーシャリングを必要とする相互運用性の問題には、多数のクラスがあります。構造体の配列を含む可変サイズの構造体および構造体は、より一般的な構造体の2つにすぎません。 –

+0

http://arnshea.blogspot.com/2009/04/interop-with-struct-that-c​​ontains-array.htmlに構造体の配列を含む構造体をマーシャリングする例を示します。あなたが手動で相互運用性のためにデータをマーシャリングしなければならないのはかなりまれです... –

0

私はここで全く専門家ではありませんが、私はコードの部分を見ていることがあります。同じことをやっている。私はあなたが探している部分は、[IN、OUT]一部だと思います。ここ

は、彼らが

[DllImport("")] 
private static extern short MethodName([In,Out] ref StructureName variable); 

をやっていることで、その後の構造上、彼らは次の属性

[StructLayout(LayoutKind.Sequential, Size = #)] 
public struct StructureName {} 

を持っていますそれはrefを経由しているので、同じデータを戻す必要があります。

コミュニティウィキとマークされているので、間違っているとこれを修正できます。

+0

これは、次のシグネチャのインポートです。short MethodName(StructureName * struct); 私はかなりシャレですが、ここでは「ESPが台無し」という例外があります。 –

4

警告:返されたポインタはすでに

は、私はあなたが探しているものと考えているCLRによって管理されるメモリにある場合にのみ動作します。これは、任意の必要性を排除すべきである

// C# import 
[DllImport("MyDll.dll")] 
[return : MarshalAs(UnmanagedType.LPStruct)] 
public static extern StructureName Function(); 

[StructLayout(LayoutKind.Sequential)] 
public class StructureName {} 

ですマニュアルMarshal.PtrToStructureが呼び出されます。構造に含まれる内容に応じて、フィールドに適宜MarshalAs属性をタグ付けする必要があります。 MSDNにはこれの良い例があります。

+0

+1、ええと、私はクラスのバージョンについて100%確信していません。 invokeのクラスは通常、ポインタ型として扱われ、structは値です。クラス型とLPStructを組み合わせることがすべてのシナリオで機能するかどうかはわかりません。 – JaredPar

+0

** MarshalAs(LPStruct)**は私が望むものを最も正確に記述します。戻り値のLPStructはP/Invoke互換ではありません: "返り値をマーシャリングできません:無効な管理対象/非管理型の組み合わせ..." –

+0

私は少しのテストを行い、その構造体は 'LPStruct'としてマーシャリングされています仕事 - 私は適切に投稿を編集します。さらに、もう1つ(かなりメジャーな)警告があります。参照先のメモリを追加してガベージコレクトしようとするため、(SimpleStruct *がCコード内の)メモリにCLRによって割り当てられている必要があります。これを投稿にも追加します。だから、あなたはIntPtrのアプローチに慣れる必要があるようです。 –

関連する問題