- 締切済み
C#からC言語で作成したDLLに文字列の配列の受け渡しをする方法を教えて下さい
初めまして、プログラミング自体経験が初心者なので根本的なところで間違っているかもしれませんがご指摘いただければと思いまして投稿します。 C#のプログラムからC言語で書かれたDLLを使いたいのですが、いくつか分からないことがあります。1つは文字列の配列の受け渡し方法、もう1つはその配列要素の文字列がマルチバイト文字である場合の方法です。 C#側 using System; using System.Runtime.InteropServices; public class MainClass { [DllImport("Cmdll.dll")] public static extern void SampleMethod([In, Out] string[] s, int x); static void Main() { string[] str1 = new string[2] {"月曜日", "火曜日"}; SampleMethod(str1, n); for (int i = 0; i < n; i++) Console.WriteLine("str1[{0}] = {1}", i, str1[i]); } } C言語側 void __declspec(dllexport) SampleMethod(char *str[], int n) { int i; for (i = 0; i < n; i++) strcat(str[i], "ですね"); } なお、私用する文字を1バイト文字にすると動作しました。 DllImportの使い方も付け焼刃なので使い方が間違っていたらご指摘願えますでしょうか。よろしくお願いいたします。環境はVisual Studio 2008です。
- みんなの回答 (3)
- 専門家の回答
みんなの回答
- nagaimoken
- ベストアンサー率0% (0/3)
StringBuilder C# DLL で検索してみてください。 参考になるかどうかはわかりませんが、URL張っておきます。
- chie65536(@chie65535)
- ベストアンサー率44% (8802/19961)
追記。 >もう1つはその配列要素の文字列がマルチバイト文字である場合の方法です。 StringToHGlobalAnsiはネイティブな文字列を返す。 コンパイラの「文字セット」オプションを「UNICODE」にすればその文字列の中身はUNICODEとなるし「マルチバイト」にすればその文字列の中身はマルチバイトになる筈。 もちろん「メイン側」と「DLL側」は、文字セットオプションを同じにしてコンパイルしなければならない。
- chie65536(@chie65535)
- ベストアンサー率44% (8802/19961)
> string[] str1 = new string[2] {"月曜日", "火曜日"}; > SampleMethod(str1, n); >void __declspec(dllexport) SampleMethod(char *str[], int n) { str1は「string[]」なのに、受け取り側で「char *[]」で受け取ろうとしてる。 「stringとchar *の違い」は「intとchar *の違い」と同じくらい違う。つまり「全然別物」って事だ。 ----- string[] str1 = new string[2] {"月曜日", "火曜日"}; char *chrstr[] = new char *[2]; for (int i = 0; i < n; i++) //ネイティブな文字列を作る。結果はグローバルヒープに勝手に確保された領域へのポインタ chrstr[i] = (char*)System::Runtime::InteropServices::Marshal::StringToHGlobalAnsi(str1[i]).ToPointer(); SampleMethod(chrstr, n); for (int i = 0; i < n; i++) Console.WriteLine("str1[{0}] = {1}", i, str1[i]); //作られたネイティブな文字列はグローバルヒープに勝手に確保された領域なので、必ず解放する for (int i = 0; i < n; i++) System::Runtime::InteropServices::Marshal::FreeHGlobal(chrstr[i]);
補足
早速のお返事ありがとうございます。 str1は「string[]」なのに、受け取り側で「char *[]」で受け取ろうとしてることが問題なことは分かりました。ありがとうございます。しかし早速実際にやってみたのですが構文エラーと出てしまいます。 char *chrstr[] = new char *[2]; や chrstr[i] = (char*) System::Runtime::InteropServices::Marshal::StringToHGlobalAnsi(str1[i]).ToPointer(); といった表現はC#で可能なのでしょうか。
お礼
情報ありがとうございます。 試してみます。