C# と VB.NET の質問掲示板

ASP.NET、C++/CLI、Java 何でもどうぞ

C# と VB.NET の入門サイト

Re[2]: 構造体配列のマーシャリングについて


(過去ログ 31 を表示中)

[トピック内 4 記事 (1 - 4 表示)]  << 0 >>

■14988 / inTopicNo.1)  構造体配列のマーシャリングについて
  
□投稿者/ hanayama (6回)-(2008/02/29(Fri) 19:56:14)

分類:[C#] 

2008/02/29(Fri) 19:58:09 編集(投稿者)
2008/02/29(Fri) 19:57:14 編集(投稿者)

お世話になっております。hanayamaです。

現在、C#からC++で作成した関数を呼び出そうと奮闘しています。
C++のTest関数はP_DATA構造体のポインタを受け取るのですが、
C#からこの引数を渡すにはどうすればよいでしょうか?

C#から構造体配列を作成し、その配列のアドレスをIntPtr配列に格納しましたが、
方法が間違っている気がします。。。

どなたかご教授お願いします。

以下、ためしに作成したコードです。※正しい結果は得られませんでした。

【C++の関数定義】
int Test(P_DATA* pData);

【C++のP_DATA構造体定義】
typedf struct
{
int Stat;
char Message[32];
}


【C#側のP_DATA構造体定義】
[StructLayout(LayoutKind.Sequential, Pack = 4, CharSet = CharSet.Ansi)]
public struct P_DATA
{
public int Stat;

[MarshalAs(UnmanagedType.ByValTStr, SizeConst = 32)]
public string Message;
}

【C#の実装コード】

P_DATA[] data = new P_DATA[2];
data[0].Stat = 0;
data[0].Message = "aiueo\0";
data[1].Stat = 1;
data[1].Message = "kakikukeko\0";

 IntPtr pData = new IntPtr[2];

 pData[0] = Marshal.AllocHGlobal(Marshal.SizeOf(typeof(P_DATA)));
 pData[1] = Marshal.AllocHGlobal(Marshal.SizeOf(typeof(P_DATA)));


// 構造体アドレスをポインタへ
Marshal.StructureToPtr(data[0], pData[0], true);
Marshal.StructureToPtr(data[1], pData[1], true);

// Test関数の呼び出し
int a = Test(pData);


引用返信 編集キー/
■14993 / inTopicNo.2)  Re[1]: 構造体配列のマーシャリングについて
□投稿者/ 出水 (5回)-(2008/02/29(Fri) 22:18:32)
int Test(P_DATA* pData);
C++からこの関数を呼び出す場合、こんな感じで呼び出すんでしょうか?

P_DATA pdata[2];
int ret = Test(pdata);

C#のソースを見る限り、C++風に書くとこんな感じで呼び出していると思います(newしてないけど、概念なので)

P_DATA *pdata[2];
int ret = Test(pdata);

だとしたら、C#の部分はこれが正解っぽい気がします
int a = Test(pData[0]);

引用返信 編集キー/
■14996 / inTopicNo.3)  Re[1]: 構造体配列のマーシャリングについて
□投稿者/ myugaru (24回)-(2008/03/01(Sat) 02:20:40)
myugaru さんの Web サイト
No14988 (hanayama さん) に返信
IntPtrとか必要ありません。とりあえず答えを書いてしまいます。
わからなければ再度質問を投稿ください。


using System;
using System.Runtime.InteropServices;

namespace TestExe
{
    static class Program
    {
        [DllImport("TestDll.dll")]
        static extern int Test([In, Out]P_DATA[] pData);

        struct P_DATA
        {
            public int Stat;
            [MarshalAs(UnmanagedType.ByValTStr, SizeConst = 32)]
            public string Message;
        }

        [STAThread]
        static void Main(string[] args)
        {
            P_DATA[] data = new P_DATA[2];
            data[0].Stat = 0;
            data[0].Message = "aiueo\0";
            data[1].Stat = 1;
            data[1].Message = "kakikukeko\0";
            Test(data);
        }
    }
}

引用返信 編集キー/
■15040 / inTopicNo.4)  Re[2]: 構造体配列のマーシャリングについて
□投稿者/ hanayama (7回)-(2008/03/03(Mon) 09:19:17)
No14996 (myugaru さん) に返信
> ■No14988 (hanayama さん) に返信
> IntPtrとか必要ありません。とりあえず答えを書いてしまいます。
> わからなければ再度質問を投稿ください。
>
>
[In, Out]を使用して構造体配列のまま渡すのですか!
IntPtrは必要ないのですね、、
提示いただいた内容を試したところ、想定していた動作が確認できました。
ご回答ありがとうございます。
またよろしくおねがいします。

解決済み
引用返信 編集キー/


トピック内ページ移動 / << 0 >>

このトピックに書きこむ

過去ログには書き込み不可

管理者用

- Child Tree -