• 締切済み

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です。

みんなの回答

回答No.3

StringBuilder C# DLL で検索してみてください。 参考になるかどうかはわかりませんが、URL張っておきます。

参考URL:
www.atmarkit.co.jp/fdotnet/dotnettips/024w32api/w32api.html
phaz
質問者

お礼

情報ありがとうございます。 試してみます。

回答No.2

追記。 >もう1つはその配列要素の文字列がマルチバイト文字である場合の方法です。 StringToHGlobalAnsiはネイティブな文字列を返す。 コンパイラの「文字セット」オプションを「UNICODE」にすればその文字列の中身はUNICODEとなるし「マルチバイト」にすればその文字列の中身はマルチバイトになる筈。 もちろん「メイン側」と「DLL側」は、文字セットオプションを同じにしてコンパイルしなければならない。

回答No.1

>    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]);

phaz
質問者

補足

早速のお返事ありがとうございます。 str1は「string[]」なのに、受け取り側で「char *[]」で受け取ろうとしてることが問題なことは分かりました。ありがとうございます。しかし早速実際にやってみたのですが構文エラーと出てしまいます。 char *chrstr[] = new char *[2]; や chrstr[i] = (char*) System::Runtime::InteropServices::Marshal::StringToHGlobalAnsi(str1[i]).ToPointer(); といった表現はC#で可能なのでしょうか。

関連するQ&A