質問をすることでしか得られない、回答やアドバイスがある。

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

新規登録して質問してみよう
ただいま回答率
85.48%
DLL

DLL(Dynamic Link Library)とは、他のモジュールからも使用する事が出来る、関数とデータが格納されているモジュールのことです。

C#

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

C++

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

Q&A

解決済

1回答

2502閲覧

C++で作成したdllをC#で読み出す(構造体)

Yamatomura

総合スコア14

DLL

DLL(Dynamic Link Library)とは、他のモジュールからも使用する事が出来る、関数とデータが格納されているモジュールのことです。

C#

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

C++

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

0グッド

2クリップ

投稿2018/08/31 09:51

下記C++の関数をdllを使ってC#から読み出したいのですが、いろいろやってみて呼び出せるのですが値がうまく入らないです。
やり方を教えていただけるとありがたいです。

C++

1//C++側のexportしている関数 2extern "C" int __stdcall Calibtest( 3 CalibrationDataset calibrationDataset1[3] 4 ) 5//上記引数の構造体の中身 6struct CalibrationDataset 7 { 8 unsigned short* pCalibrationData; // 画像のポインタ 9 unsigned int iWidth; // データ幅[pixel] 10 unsigned int iHeight; // データの高さ[pixel] 11 };

試したC#のコード

C#

1//C#側の構造体の定義 2public struct CalibrationDataset 3 { 4 public IntPtr pCalibrationData; 5 public uint iWidth; 6 public uint iHeight; 7 } 8 9//C#側の呼び出す関数の定義 10[DllImport("aaa.dll", CallingConvention = CallingConvention.StdCall)] 11public extern static int Calibtest( 12 ref CalibrationDataset[] calibrationDataset_ 13 ); 14

実際に呼び出している部分

C#

1 2CalibrationDataset[] calibrationDataset1 = new CalibrationDataset[3]; 3 4calibrationDataset1[0].pCalibrationData = Marshal.AllocCoTaskMem(Marshal.SizeOf(typeof(ushort)) * calib1.Data.Length); 5CopyUshortToIntptr(calib1.Data, calibrationDataset1[0].pCalibrationData, calib1.Data.Length); 6calibrationDataset1[0].iWidth = (uint)calib1.Width; 7calibrationDataset1[0].iHeight = (uint)calib1.Height; 8 9 10calibrationDataset1[1].pCalibrationData = Marshal.AllocCoTaskMem(Marshal.SizeOf(typeof(ushort)) * calib2.Data.Length); 11CopyUshortToIntptr(calib2.Data, calibrationDataset1[1].pCalibrationData, calib2.Data.Length); 12calibrationDataset1[1].iWidth = (uint)calib2.Width; 13calibrationDataset1[1].iHeight = (uint)calib2.Height; 14 15 16 17calibrationDataset1[2].pCalibrationData = Marshal.AllocCoTaskMem(Marshal.SizeOf(typeof(ushort)) * calib3.Data.Length); 18CopyUshortToIntptr(calib3.Data, calibrationDataset1[2].pCalibrationData, calib3.Data.Length); 19calibrationDataset1[2].iWidth = (uint)calib3.Width; 20calibrationDataset1[2].iHeight = (uint)calib3.Height; 21 22//※calib1,calib2,calib3は画像データを指しています 23 24 Calibtest( 25 ref calibrationDataset1, 26 );

上記コードの中の関数詳細

C#

1private static void CopyUshortToIntptr(ushort[] arr, IntPtr ptr, int length) 2 { 3 short[] temp = new short[length]; 4 Buffer.BlockCopy(arr, 0, temp, 0, temp.Length * Marshal.SizeOf(typeof(ushort))); 5 Marshal.Copy(temp, 0, ptr, temp.Length); 6 }

C++の引数がCalibrationDataset calibrationDataset1[3]でなく
CalibrationDataset calibrationDataset1と配列数指定じゃなきゃうまくいくのですが、インターフェースの仕様上変更するのができなく教えていただけると嬉しいです。

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

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

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

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

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

guest

回答1

0

ベストアンサー

Calibtest内で値を変更してマネージ側で受け取る必要がありますか?
その場合はrefではなくIn,Out属性を付けてみてください。
マネージに渡すだけでいいならIn属性だけでいいはずです。

C#

1[DllImport("MarshalDll.dll", CallingConvention = CallingConvention.StdCall)] 2public extern static int Calibtest( 3 [In, Out] CalibrationDataset[] calibrationDataset_ 4); 5 6Calibtest(calibrationDataset1);  // 呼び出しは何もなし

投稿2018/08/31 17:24

toki_td

総合スコア2850

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

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

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

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

ただいまの回答率
85.48%

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

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

質問する

関連した質問