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

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

詳細はこちら
C#

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

Q&A

解決済

1回答

775閲覧

呼び出しているCのdllに値をセットした構造体配列を渡して、その構造体配列から結果を受領したい。

退会済みユーザー

退会済みユーザー

総合スコア0

C#

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

0グッド

0クリップ

投稿2020/12/21 05:50

C#よりC/C++で作成したDLLを呼び出す必要があります。
C/C++よりDLLを呼び出す場合は、あらかじめバッファーを確保した構造体配列を定義して呼び出し、結果を同じ構造体で取得できます。構造体一つ一つには文字列の上限をセットする必要があります。
この場合の、C#からC/C++のDLLをどうやって呼び出せばデータを取得できるのでしょうか?

C/C++のDLL struct Test { int nLen ;                // (I) 最大読み込みサイズ char *lpszWord ; // (O) 読み込まれた文字列 } // 呼出形式 int GetWord(int nData, Test typDmy[]);

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

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

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

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

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

退会済みユーザー

退会済みユーザー

2020/12/21 06:12 編集

バッファーを確保した構造体を渡すとありますが、メモリアロケータは何を使用しているのですか? 呼び出し側で確保しないといけないなら、どのWinAPIで確保・解放するかを仕様で定めておくか(例えばCoTaskMemAlloc,CoTaskMemFree)、DLL側でアロケーション・解放用関数を用意しておく必要があります。
退会済みユーザー

退会済みユーザー

2020/12/21 06:13

DLL側は解放できませんので、呼び出し側で確保する必要があります。 確保方法も含めて解答いただけませんでしょうか?
退会済みユーザー

退会済みユーザー

2020/12/21 07:18 編集

よく考えたら、DLL側で解放しないので最初のコメントは関係ありませんでした。最初のコメントは無視してください。
guest

回答1

0

ベストアンサー

とりあえず雑にサンプル組んでみましたが、公式のドキュメントも目を通して、理解した上で運用してください。DLL名、文字コード、呼び出し規約はDLLに合わせて適時変更してください。
ネイティブ相互運用性

C#

1using System; 2using System.Collections.Generic; 3using System.Runtime.InteropServices; 4using System.Text; 5 6namespace Console_Core 7{ 8 [StructLayout(LayoutKind.Sequential)] 9 public struct Test 10 { 11 public int nLen; 12 public IntPtr lpszWord; 13 } 14 15 class Program 16 { 17 [DllImport("Dll1.dll", CharSet = CharSet.Ansi, CallingConvention=CallingConvention.Cdecl)] 18 private static extern int GetWord(int nWord, Test[] test); 19 20 static void Main(string[] args) 21 { 22 var tests = new Test[1]; 23 tests[0].nLen = 10; 24 tests[0].lpszWord = Marshal.AllocCoTaskMem(tests[0].nLen); 25 GetWord(1, tests); 26 string word = Marshal.PtrToStringAnsi(tests[0].lpszWord); 27 Marshal.FreeCoTaskMem(tests[0].lpszWord); 28 Console.WriteLine(word); 29 30 Console.ReadLine(); 31 } 32 } 33}

投稿2020/12/21 07:29

編集2020/12/21 07:37
退会済みユーザー

退会済みユーザー

総合スコア0

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

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

退会済みユーザー

退会済みユーザー

2020/12/22 08:24

解答ありがとうございました。 おかげさまで、問題となったプログラムが完成できました。 追加ですが、最初は最大取り込み可能文字列をセットして、セットされた文字数が同一変数から返ってくる場合は、DLLの定義にて[In, Out]が必要なこともわかりました。参考として追記しておきます。
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

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

ただいまの回答率
85.36%

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

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

質問する

関連した質問