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

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

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

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

C#

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

ポインタ

ポインタはアドレスを用いてメモリに格納された値を"参照する"変数です。

C++

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

Q&A

解決済

1回答

4013閲覧

C++で作成したDLLの返すfloat型配列のポインタをC#で受け取り、各要素を参照したい

marusa

総合スコア17

DLL

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

C#

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

ポインタ

ポインタはアドレスを用いてメモリに格納された値を"参照する"変数です。

C++

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

0グッド

0クリップ

投稿2020/10/05 05:50

前提・実現したいこと

前提
C++で作成したDLL "Sample.dll"があります。
"Sample.dll"に以下のような関数"sample_return_ptr"があります。

  • 入力 なし
  • 出力 float *
  • 動作 関数内でfloat型の配列を動的に確保し、そのポインタを返す
  • 配列の要素数は、呼び出す側からは見えません

上記の"sample_return_ptr"をC#から呼び出すことを想定します。
この時に、"sample_return_ptr"から返された配列へのポインタを利用して、C#ではfloat配列として利用したいと考えています。

発生している問題・エラーメッセージ

配列の要素数が不明な場合に、どのようにするかがわからない。

該当のソースコード

C++

1class __declspec(dllexport) Sample{ 2public: 3 float* sample_return_ptr(){ 4 //例として要素数5. nは任意の整数としてください。 5 int n = 5; 6 float* ret = (float *)malloc(sizeof(float) * n); 7 8 return ret; 9 } 10}

C#

1//この関数で受け取るIntPtrの扱いをどのようにすればよいのか 2[DllImport("Sample.dll")] 3extern IntPtr sample_return_ptr();

試したこと

このページにたどり着き、参考にしてポインタを返す関数の呼び出し自体はできそうな状態です。
参考にした内容では、予め配列の要素数が分かっている状態?(文字列なので配列と言っていいのかは微妙ですが、文字列の長さが分かっている状態)のため、要素数が不明な場合はどうすればいいのかで止まってしまいました。

補足情報(FW/ツールのバージョンなど)

64bit Windows
C++11以降
Visual Studio 2015 Pro

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

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

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

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

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

dodox86

2020/10/05 06:00

> 要素数が不明な場合はどうすればいいのかで止まってしまいました。 DLLの関数内で生成した配列の要素数が不明な場合、C/C++からC#に限ったことではなく、呼び出し側では正しい要素数を把握できず、正しく処理を続行できないはずですがその辺はどうなっているのでしょうか。
marusa

2020/10/05 06:36

コメントありがとうございます。 そうですね、指摘頂いた内容はその通りです。 もともとvectorを返していた関数をdllにしようとしたのに伴い変更していたため 基本を失念しておりました。ご指摘ありがとうございます。
guest

回答1

0

ベストアンサー

C言語の配列はC#のそれと違い、受け取った側から配列のサイズを判定する事は出来ません。
構造体にしてサイズも一緒に返すようにするか、サイズ出力用のパラメータを用意する必要があります。

あと、class __declspec(dllexport) Sample でクラスごとエクスポートしてますが、多分C#からは使えません。
関数単位でエクスポートする必要があると思います。

投稿2020/10/05 06:03

編集2020/10/05 06:26
退会済みユーザー

退会済みユーザー

総合スコア0

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

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

marusa

2020/10/05 06:44

回答ありがとうございます。 基本的なことを失念しておりました。別解を教えて頂き助かりました。 クラスごとのエクスポートだと利用できないというものが気になったのですが、 どういう意味なのでしょうか。 C++のクラスごとエクスポートすることで、そのクラスのパブリックメンバ全てが エクスポートされているのと同じ意味だと理解していたのですが、誤りということなのでしょうか。 (こちらを参考にしています。 https://docs.microsoft.com/ja-jp/cpp/build/exporting-from-a-dll-using-declspec-dllexport?view=vs-2019) お手数ですが、よろしければご教授いただければ幸いです。
退会済みユーザー

退会済みユーザー

2020/10/05 07:19 編集

> C++のクラスごとエクスポートすることで、そのクラスのパブリックメンバ全てが > エクスポートされているのと同じ意味だと理解していたのですが、誤りということなのでしょうか。 エクスポート自体はされますが、C#から容易に利用できる形ではない、という事です。 https://ja.stackoverflow.com/questions/10657/ このリンク先を見て貰った方がいいと思います。 実際に何がエクスポートされているかは、Dependencies( https://github.com/lucasg/Dependencies ) 辺りを使ってDLLを覗いて見た方がよいでしょう。 mallocで確保したポインタを返す場合は、解放用の関数も用意しておくのを忘れないようにしてください。メモリリークします。
marusa

2020/10/05 07:24

ご回答ありがとうございます。 リンク先読ませて頂いて納得しました。教えて頂いて大変有難いです。 最後の注意についても有難いです。指摘していただけなければおそらくやっていたと思います。 ご丁寧に対応いただき、本当にありがとうございました。
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

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

ただいまの回答率
85.35%

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

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

質問する

関連した質問