• ベストアンサー

'StructLayout' の仕様について

.NET C++の構造体のマーシャリングについて勉強中です。 構造体のマーシャリングに 'StructLayoutAttribute' を用いる場合、 [StructLayout(LayoutKind::Sequential, Pack=8)]などと記述するようですが、msdnのドキュメントから 'StructLayout' の仕様を探すことができませんでした。 'StructLayoutAttribute'クラスの仕様はあり、おそらくこれと関連しているとは思うのですが、そのメンバやメソッドに 'StructLayout' がありません。 このあたりの理解を得るためのヒントを頂けると幸いです。 宜しくお願いします。

質問者が選んだベストアンサー

  • ベストアンサー
回答No.2

http://msdn.microsoft.com/en-us/library/bfz783fz.aspx >By convention, all attribute names end with Attribute. However, several languages that target the runtime, such as Visual Basic and C#, do not require you to specify the full name of an attribute. For example, if you want to initialize System..::.ObsoleteAttribute, you only need to reference it as Obsolete. =========== その他、ユーザー定義の属性の作り方とその使用法 http://msdn.microsoft.com/en-us/library/84c42s56.aspx#cpcondeclaringattributeclass

_hitoshi_
質問者

お礼

'Attribute' を省略できるということですね。 回答ありがとうごさいました。

その他の回答 (1)

  • reset_cat
  • ベストアンサー率68% (94/138)
回答No.1

[StructLayout(LayoutKind::Sequential, Pack=8)] の'StructLayout'の部分は、StructLayoutAttributeクラスのコンストラクタにあたります。コンストラクタの仕様を見ると、引数にLayoutKind列挙値を取るのがわかると思います。 続く'Pack=8'は、StructLayoutAttributeクラスのPackプロパティに8を設定する・・・という意味になります。

_hitoshi_
質問者

お礼

回答ありがとうごさいました。

関連するQ&A

  • C++/C#間での構造体の引き渡し方法に関して

    現在、C++で作成したクラスを、 C#から呼び出し実行しようとしております。 引数として、構造体を利用したいので、 C++側、C#側でそれぞれ下記のように 構造体を定義しました。 【C++】 typedef struct _Msg { ULONG Code; ULONG sessionId; }Msg; 【C#】 [StructLayout(LayoutKind.Sequential)] public struct Msg { public uint Code; public uint sessionId; } そして、下記のようにC++側で定義したクラスを C#側で呼び出そうとしたのですが、 「Msg*から_Msg*に変換できません」という コンパイルエラーが発生してしまいました。 構造体の定義は同じものになっていると思うのですが、 この原因は何だと考えられるでしょうか。 よろしくお願いいたします。 【C++】 ULONG Wrap::API( Msg* sample_Msg ) { return 1; } 【C#】 Msg sample_msg; Wrap.API(&sample_msg);

  • VB2005でバイト配列をコピーするには

    どなたかご教授下さい。 VB6で作成したプログラムをVB2005にコンバートしました。構造体からなる配列変数を一つの配列変数にコピー したいのですが、構造体の最初のメンバーだけ値が同じで以降の値は正しくセットされていませんでした。 どのように記述したらよいのでしょうか。またCopymMemory以外で良い方法があればご教授下さい。 よろしくお願い致します。 ===概略=== Declare Sub CopyMemory Lib "kernel32" Alias "RtlMoveMemory" (ByRef Destination As Byte, ByRef Source As Byte, ByVal Length As Short) 構造体定義 (コピー元) <StructLayout(LayoutKind.Sequential)>Structure ST_MOTO <MarshalAs(UnmanagedType.ByValArray, SizeConst:=4)> Dim byte_strTranCd() As Byte <MarshalAs(UnmanagedType.ByValArray, SizeConst:=5)> Dim byte_strTanSeq() As Byte <MarshalAs(UnmanagedType.ByValArray, SizeConst:=2)> Dim byte_strTxtNo() As Byte <MarshalAs(UnmanagedType.ByValArray, SizeConst:=3)> Dim byte_strTxtSeq() As Byte End Structure Dim A As ST_MOTO (コピー先) <StructLayout(LayoutKind.Sequential)> Structure ST_SAKI Dim lngrecLen As Integer 'データのLength <MarshalAs(UnmanagedType.ByValArray, SizeConst:=100)> Dim bytrecData() As Byte 'データ End Structure Dim B As ST_SAKI Call CopyMemory(B.bytrecData(0), A.byte_strTranCd(0), 14) 出力結果 '最初の構造体のメンバーの値は正しく設定されている B.bytrecData(0) =80    A.byte_strTranCd(0) =80 B.bytrecData(1) =50    A.byte_strTranCd(1) =50 B.bytrecData(2) =57    A.byte_strTranCd(2) =57 B.bytrecData(3) =50    A.byte_strTranCd(3) =50 'これ以降は正しくない。(VB6だと正しく設定されている) B.bytrecData(4) =0     A.byte_strTanSeq(0) =80 B.bytrecData(5) =0     A.byte_strTanSeq(1) =87 B.bytrecData(6) =0     A.byte_strTanSeq(2) =48 B.bytrecData(7) =0     A.byte_strTanSeq(3) =48 B.bytrecData(8) =6     A.byte_strTanSeq(4) =55     ・              ・     ・              ・

  • VC#からdll関数を使う

    c#(vs2003)から、c++で書かれたdllの中に含まれる関数を読み込む部分を書いています。この関数は以下のように定義 され、構造体のポインタを返り値として返します。 SENSOR* GetSensor(); SENSOR構造体はdllの中では以下のように定義されています。 typedef struct{   int type; unsigned short param; char name[64]; DWORD con_pos; } SENSOR; これをc#のコードの中で読み込むため、c#のクラスの中で、以下のように再定義しました。 [StructLayout(LayoutKind.Sequential)] public struct SENSOR {   public int type;   public ushort param;   public string name;   public uint con_pos; } 後にc#のコードの中に、dllの中の関数を呼び出す定義を以下のように書きました。 [DllImport("sensor.dll"); public static extern SENSOR* GetSensor(); ここで SENSOR* sensor = GetSensor(); といった感じでdllをの関数を使って値を取得するようにしたのですが、実行すると 「return value をマーシャル できません : ポインタはマーシャルされた構造体を参照できません。」 といったエラーが出ます。いろいろと調べたのですが解決方法がわかりません。アドバイスをいただけたら幸いです。

  • 構造体の静的な初期化

    構造体の静的な初期化で、初期化が書かれていないメンバーは、 どうなるのでしょうか。。? たとえば・・・ // 構造体の宣言 strcut MY_STRUCT {    int data1 ;    int data2 ;    int data3 ;    int data4 ; } ; // 変数宣言&初期化 static strcut MY_STRUCT st = {    .data1 = 100,    .data3 = 300 } ; ネットで調べると、 初期化で指示されていないメンバーは0に初期化される、 という記述も一つだけ見つけたのですが・・・これはC言語(C99)の仕様でしょうか? それともコンパイラ依存の仕様でしょうか?

  • C#で作成したdllをVBScriptで使うときのマーシャリングの問題

    お世話になります。 現在ClassicASPでWebアプリケーションを開発しているのですが、 その時にC#で作成したdllを使用したいと思い、 COM登録をしてASP側ではServer.CreateObjectで使用しようとしています。 しかし、データの受け渡し部分でずっとつまづいています。 やりたいことは、C#側の関数の戻り値で独自のクラス(構造体)の配列を戻したいのです。 以下サンプルコードです。 ASP側 <%@ Language=VBScript%> <% Response.ContentType = "text/html" Dim testObject set testObject = Server.CreateObject("TestObject") list = testObject.getList() Response.Write(TypeName(list)) ' ここで、[VBScript でサポートされていないオートメーションが変数で使用されています]エラー %> C#側 [StructLayout(LayoutKind.Sequential)] public struct TestData { [MarshalAs(UnmanagedType.BStr, SizeConst = 1024)] public String title; } public interface ITestObject { TestData[] getList(); } public class TestObject : ITestObject { public TestData[] getList() { TestData[2] result; result[0].title = "1"; result[1].title = "2"; return result; } } あとどういった処理が足りないのでしょうか? やりたいことは、構造体配列をASP側に渡したいだけです。 本当に困っています、なにとぞ宜しくお願い致します。

  • C++では構造体がメンバ関数をもてることについて

    仕事ではC言語を使っています。7年ぶりくらいにC++を勉強しなおす気になりました。勉強し始めて疑問に思ったことがあります。 C++では構造体もメンバ関数やコンストラクタ、デストラクタをもてるようですが、なぜそのような仕様になったのでしょうか?クラスでできることをわざわざ構造体(や共用体)でも出来る必要性を感じません。(きらいなら使わなければいいだけのことですが。) 学生時代にC++を勉強したとき使っていた本(※)にそのような記述が無かったような気がします。 ※柴田望洋著:プログラミング講義C++、ソフトバンクブックス、1997 なぜそのような仕様になっているのか、経緯や必要性について教えてください。

  • XMLパーサー(であってるのかな?)について

    いつもお世話になっています。 VB6.0でXMLファイルを読み込むプログラムを修正しています。 参照設定で「Microsoft XML,version2.0(msxml.dll)」というのを使用しています。 そこで、みなさんにお伺いしたいのが、 このオブジェクトのヘルプファイルの場所なんです。 正直言っていろいろなメンバーがあったり、メソッドがあったり しても、何を書いてるのか「やんわりと」しかわかりません(;_;) MSDNでそれらしきライブラリを見つけたのですが、 微妙に名前が違ってて、それでもいいのかわからず・・・ ヘルプドキュメント(MSDNなど)の場所をご存知の方 いらっしゃいましたら、教えて下さい。 自分でみつけたのは 1 http://www.microsoft.com/japan/msdn/library/default.asp?url=/japan/msdn/library/ja/cpref/html/frlrfsystemxmlxmlnodememberstopic.asp 2 http://www.microsoft.com/japan/msdn/xml/general/beginner.asp#What でした。これであってるのでしょうか? 2は、まさにやってるのは「これ」なんですが、あまりにも概要だけで、細かい処理の内容までわかりません。 みなさんよろしくお願いします。

  • C#の構造体の開放のしかた

    C#について質問なのですが、たとえば System.Drawing.GraphicsクラスはメンバのDisposeメソッドを呼び出せば開放できるんですよね。 じゃあSystem.Int32などの構造体ってどうやって開放(破棄)するんですか??教えてください!

  • VB2008: 構造体に関連して・・・。

    VB.Net を知って60日という初学者です。 プログラマではなくデザイナ。 ですから、未だに Sub Main() で基本事項の確認中です。 フォームなどの演習は、まーだ、当分はしない予定です。 さて、質問は構造体に関するMSDN の記述です。 >構造体の要素が文字列型 (String) やオブジェクト型 (Object) などの参照型である場合は、 >データへのポインタがコピーされます。 この下り。 「なんでポインタがコピーされるんや」という疑問を抱きました。 ・文字列型にプロパティやメソッドという機能を付加するためにクラス型にした。 ・クラス型は、「・・・・」ということで参照型。と ・「・・・・」と同じ理由。 というように背景を推測しました。 この推測も単なるど素人の推測。 当を得たいるか?実に怪しい物。 仮に当らずとも遠からずとしても、肝心の「・・・・」がわかりません。 この辺りに関して、「このように考えてたらよい」という回答がありましたらお願いします。

  • VB2008: 構造体に関するMSDNの解釈について!

    ' ================== ' 構造体変数の代入 ' ================== Module theTEST   Private Structure TEST4     Dim MembersCount As Integer     Dim Member1 As String     Dim Member2 As String   End Structure   Sub Main()     Dim T4_1 As TEST4     Dim T4_2 As TEST4     T4_1.MembersCount = 1     T4_1.Member1 = "T4_1:Member1"     T4_1.Member2 = "T4_1:Member2"     T4_2 = T4_1     Debug.Print(T4_2.MembersCount.ToString)     Debug.Print(T4_2.Member1)     Debug.Print(T4_2.Member2)   End Sub End Module [イミディエイト ウインドウ] 1 T4_1:Member1 T4_1:Member2 >構造体の要素が文字列型 (String) やオブジェクト型 (Object) などの参照型である場合は、データへのポインタがコピーされます。 (http://msdn.microsoft.com/ja-jp/library/18ytyskd(VS.80).aspx) このMSDNライブラリの説明によると、 [イミディエイト ウインドウ] 0 T4_1:Member1 T4_1:Member2 という結果を得るというのが私の予測。 もしかしたら、MSDNライブラリの説明の舌足らず。 >構造体の要素が値型であらば値がコピーされますが、文字列型 (String) やオブジェクト型 (Object) などの参照型である場合は、データへのポインタがコピーされます。 ということでしょうか?

専門家に質問してみよう