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

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

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

C言語は、1972年にAT&Tベル研究所の、デニス・リッチーが主体となって作成したプログラミング言語です。 B言語の後継言語として開発されたことからC言語と命名。そのため、表記法などはB言語やALGOLに近いとされています。 Cの拡張版であるC++言語とともに、現在世界中でもっとも普及されているプログラミング言語です。

DLL

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

C#

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

Q&A

解決済

1回答

10484閲覧

C言語で作った自作DLLの関数(文字列型の配列)をC#で呼ぶ場合2

TAKAYASU

総合スコア146

C

C言語は、1972年にAT&Tベル研究所の、デニス・リッチーが主体となって作成したプログラミング言語です。 B言語の後継言語として開発されたことからC言語と命名。そのため、表記法などはB言語やALGOLに近いとされています。 Cの拡張版であるC++言語とともに、現在世界中でもっとも普及されているプログラミング言語です。

DLL

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

C#

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

2グッド

1クリップ

投稿2016/08/29 11:08

度々失礼いたします。

前回、C言語で作った自作DLLの関数をC#呼ぶ際に
文字列型の配列を引数にして、受け渡しをすることができた者です。

###現状
文字列型の配列を自作DLL内にある関数に渡すことができました。
以下コードになります。

C

1[DLL側] 2int TestArray(char *test,int size){ 3 for(int i = 0;i<size;i++){ 4 printf("%s\n",&test[i]); 5 } 6 return 0; 7}

C#

1[呼び出し側] 2 class Program 3 { 4 [DllImport("TestArrayDLL.dll", CharSet = CharSet.Ansi, CallingConvention = CallingConvention.Cdecl)] 5 private extern static int TestArray([In, MarshalAs(UnmanagedType.LPArray, 6 ArraySubType = UnmanagedType.LPWStr,SizeParamIndex = 1)]string[] test, int split); 7 static void Main(string[] args) 8 { 9 string[] test = { "a", "b", "c", "d", "e"}; 10 TestArray(test, test.Length); 11 Console.ReadLine(); 12 } 13 }

###やりたいこと
文字列型の配列に格納されている文字列を出力(abcde)したい。
###問題点
上記コードを実行すると出力される文字列が**「文字化け」**を起こし、望む結果を得ることができていません。

###試したこと
StringBuilderクラスを使ってみましたが結果はSystem.String[]という文字が連続で表示されました。

C#

1[呼び出し側] 2 class Program 3 { 4 [DllImport("TestArrayDLL.dll", CharSet = CharSet.Ansi, CallingConvention = CallingConvention.Cdecl)] 5 private extern static int TestArray([In, MarshalAs(UnmanagedType.LPStr)]StringBuilder test, int split); 6 static void Main(string[] args) 7 { 8 string[] test = { "a", "b", "c", "d", "e"}; 9 StringBuilder build = new StringBUilder(5); 10 build.Append(test); 11 12 TestArray(build, build.Length); 13 Console.ReadLine(); 14 } 15 }

###推察
1.もしかしたら参照渡しが完璧ではないのかもしれない?
2.渡した文字列を何かしらの方法で変換する必要がある?

前回と似たような質問になってしまい申し訳ありません。
アドバイス等頂けるとありがたいです。。。

hihijiji, ikuwow👍を押しています

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

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

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

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

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

guest

回答1

0

ベストアンサー

2つ間違いがあります。

  1. UnmanagedType.LPWStr はUTF-16の文字列(wchar_t*)になります。

DLL側がchar*で受け取るなら UnmanagedType.LPStr を使用します。

  1. DLL側は渡されるのは文字列(char*)の配列なのでchar**です。

C

1int TestArray(char **test,int size){ // * -> ** 2 for(int i = 0;i<size;i++){ 3 printf("%s\n", test[i]); // &test[i] -> test[i] 4 } 5 return 0; 6}

投稿2016/08/29 12:29

toki_td

総合スコア2850

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

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

TAKAYASU

2016/08/29 16:04

わかりやすい解説ありがとうございます! >1.UnmanagedType.LPWStr はUTF-16の文字列(wchar_t*)になります。 DLL側がchar*で受け取るなら UnmanagedType.LPStr を使用します。 LPWStrにはその様な意味があったのですね。。。 調べても当サイトのような質問と回答の記事が多く、何故このようなプロパティを使用しているのか完全理解までには至っていなかったのでとてもためになりました。 >2.DLL側は渡されるのは文字列(char*)の配列なのでchar**です。 言われてから気づきました。。。 おっしゃる通り文字列の配列なのでポインタのポインタになります。 つまるところ、参照渡しが完璧でなかったという結論を出すことができました。 教えていただきありがとうございました!
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

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

ただいまの回答率
85.48%

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

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

質問する

関連した質問