【お題】動物のキャッチフレーズ

初めまして、プログラミング自体経験が初心者なので根本的なところで間違っているかもしれませんがご指摘いただければと思いまして投稿します。

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

A 回答 (3件)

StringBuilder C# DLL で検索してみてください。


参考になるかどうかはわかりませんが、URL張っておきます。
    • good
    • 0
この回答へのお礼

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

お礼日時:2009/04/04 08:05

追記。



>もう1つはその配列要素の文字列がマルチバイト文字である場合の方法です。

StringToHGlobalAnsiはネイティブな文字列を返す。

コンパイラの「文字セット」オプションを「UNICODE」にすればその文字列の中身はUNICODEとなるし「マルチバイト」にすればその文字列の中身はマルチバイトになる筈。

もちろん「メイン側」と「DLL側」は、文字セットオプションを同じにしてコンパイルしなければならない。
    • good
    • 0

>    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#で可能なのでしょうか。

補足日時:2009/03/06 16:51
    • good
    • 0

お探しのQ&Aが見つからない時は、教えて!gooで質問しましょう!