🎄teratailクリスマスプレゼントキャンペーン2024🎄』開催中!

\teratail特別グッズやAmazonギフトカード最大2,000円分が当たる!/

詳細はこちら
C#

C#はマルチパラダイムプログラミング言語の1つで、命令形・宣言型・関数型・ジェネリック型・コンポーネント指向・オブジェクティブ指向のプログラミング開発すべてに対応しています。

Unity

Unityは、Unity Technologiesが開発・販売している、IDEを内蔵するゲームエンジンです。主にC#を用いたプログラミングでコンテンツの開発が可能です。

C++

C++はC言語をもとにしてつくられた最もよく使われるマルチパラダイムプログラミング言語の1つです。オブジェクト指向、ジェネリック、命令型など広く対応しており、多目的に使用されています。

Q&A

解決済

1回答

730閲覧

C#で確保した構造体をC++へ渡したい

Aya_program

総合スコア30

C#

C#はマルチパラダイムプログラミング言語の1つで、命令形・宣言型・関数型・ジェネリック型・コンポーネント指向・オブジェクティブ指向のプログラミング開発すべてに対応しています。

Unity

Unityは、Unity Technologiesが開発・販売している、IDEを内蔵するゲームエンジンです。主にC#を用いたプログラミングでコンテンツの開発が可能です。

C++

C++はC言語をもとにしてつくられた最もよく使われるマルチパラダイムプログラミング言語の1つです。オブジェクト指向、ジェネリック、命令型など広く対応しており、多目的に使用されています。

0グッド

0クリップ

投稿2020/12/28 01:58

Unity上でC#で確保した構造体をC++へ渡したいのですが
C#で同じ構造体を作成しポインタへ返還する際に落ちてしまいます

C++構造体

C++

1typedef struct { 2 byte Data[100]; 3} STRUCT_CPP;

C#構造体

C#

1public struct STRUCT_CS 2{ 3 public byte[] Data; 4} ;

Unity上でやろうとしていること

C#

1using System.Collections; 2using System.Collections.Generic; 3using System.Runtime.InteropServices; 4using System; 5using UnityEngine; 6using UnityEngine.UI; 7 8public class StructTest : MonoBehaviour { 9 10 private IntPtr pSt; 11 12 // Use this for initialization 13 void Start () { 14 pSt = Marshal.AllocHGlobal(Marshal.SizeOf(typeof(STRUCT_CS)); 15 16 STRUCT_CS st; 17 st.Data = new byte[100]; 18 st.Data[0] = 10; 19 Marshal.StructureToPtr(st, pSt, false); 20 21 } 22 23} 24

この状態でUnityからブレークを貼ると
Marshal.StructureToPtr(st, pSt, false);
で次の行に行けなくなってしまいます

気になる質問をクリップする

クリップした質問は、後からいつでもMYページで確認できます。

またクリップした質問に回答があった際、通知やメールを受け取ることができます。

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

guest

回答1

0

ベストアンサー

構造体の宣言がC++側と合っていないですね。
こちらが参考になるかもしれません。
uint配列を含む構造体の共有メモリへのマッピング
ネイティブ相互運用性


苦戦されているようなので、簡単なサンプルを追記します。

CS

1using System; 2using System.Diagnostics; 3using System.Runtime.InteropServices; 4 5namespace ConsoleApp1 6{ 7 class Program 8 { 9 [StructLayout(LayoutKind.Sequential)] 10 public struct STRUCT_CS 11 { 12 [MarshalAs(UnmanagedType.ByValArray, SizeConst = 10)] 13 public byte[] Data; 14 }; 15 16 //Dataを逆並びにするだけの関数 17 [DllImport("DllTest.dll", CallingConvention = CallingConvention.StdCall)] 18 static extern void Test([In]ref STRUCT_CS stIn, [Out]out STRUCT_CS stOut); 19 20 static void Main(string[] args) 21 { 22 try 23 { 24 var stIn = new STRUCT_CS(); 25 var stOut = new STRUCT_CS(); 26 27 //入力側構造体に0-9をセット 28 stIn.Data = new byte[10]; 29 for (var i = 0; i < stIn.Data.Length; i++) 30 { 31 stIn.Data[i] = (byte)i; 32 } 33 34 //入力側の内容を逆並びにする 35 Test(ref stIn, out stOut); 36 37 //出力側構造体の中身を表示 38 for (var i = 0; i < stOut.Data.Length; i++) 39 { 40 Console.WriteLine(stOut.Data[i]); 41 } 42 } 43 catch (Exception ex) 44 { 45 Debug.WriteLine(ex.ToString()); 46 } 47 48 Console.ReadLine(); 49 } 50 } 51} 52 53(実行結果) 549 558 567 576 585 594 603 612 621 630

一応DLL側も

C++

1typedef struct { 2 unsigned char Data[10]; 3} STRUCT_CPP; 4 5extern void __stdcall Test(STRUCT_CPP* pstIn, STRUCT_CPP* pstOut) 6{ 7 for (int i=0; i<10; i++) 8 { 9 pstOut->Data[9-i] = pstIn->Data[i]; 10 } 11}

投稿2020/12/28 02:51

編集2020/12/29 08:15
退会済みユーザー

退会済みユーザー

総合スコア0

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

Aya_program

2020/12/28 05:16

ありがとうございます 求めていた知識だったので助かりました 実際にunsafeを使用するかはわかりませんが・・・ unsafeを使用しないでは構造を変えなければいけなそうなので考え直してみたいと思います
退会済みユーザー

退会済みユーザー

2020/12/28 05:25 編集

リンク先は共有メモリという構造体のメモリ配置が重要になるケースのためunsafe structを使う必要がありましたが、通常はMarshalAsで配列のサイズを指定してやれば、P/InvokeやMarshalクラスを経由した時に変換を行ってくれるので、unsafe無しで受け渡しできると思います。
Aya_program

2020/12/28 05:24

MarshalAsですね調べてきます!
Aya_program

2021/01/06 04:39

遅くなってしまい申し訳ありません こちらで再度質問させていただきます MarshalAsを使用し以下のような構造体を作成したのですがうまく値を渡すことができませんでした 使用方法が間違っているのでしょうか? public struct STRUCT_CS { [MarshalAs(UnmanagedType.ByValArray, SizeConst = 100)] public byte[] Data; } ;
退会済みユーザー

退会済みユーザー

2021/01/06 23:46 編集

StructLayout指定がされてないですね。私のサンプルコードのように実装すれば渡せると思いますが。構造体だけではなく、C++側の関数宣言と、C#側の関数宣言はきちんと一致しているのでしょうか。 あと、うまく値を渡すことができないというのでは伝わらないので、どこまで正しく動作しているかが重要ですので正確に書いてください。(DLL関数を呼んだ直後に例外が発生する、DLL関数の呼び出しまでは出来ているがデータが変わっている、例外メッセージ等)
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

15分調べてもわからないことは
teratailで質問しよう!

ただいまの回答率
85.36%

質問をまとめることで
思考を整理して素早く解決

テンプレート機能で
簡単に質問をまとめる

質問する

関連した質問