214523 ランダム
 ホーム | 日記 | プロフィール 【フォローする】 【ログイン】

お気楽プログラマーのトラブルいろいろ

お気楽プログラマーのトラブルいろいろ

【毎日開催】
15記事にいいね!で1ポイント
10秒滞在
いいね! --/--
おめでとうございます!
ミッションを達成しました。
※「ポイントを獲得する」ボタンを押すと広告が表示されます。
x

PR

キーワードサーチ

▼キーワード検索

プロフィール

ふわふわふふふ

ふわふわふふふ

カレンダー

楽天カード

お気に入りブログ

まだ登録されていません

コメント新着

お気楽主婦@ Re:助かりました(02/09) 昔の記事ですが、お役に立ててよかったで…
nick@ 助かりました 私もx64とx86で開発してます。 ありがと…
excel 2010 新機能 マクロは便利です!@ excel 2010 新機能 vbaは便利です! vbaをマスターする簡単な方法は、マクロを…

フリーページ

ニューストピックス

2010年02月10日
XML
カテゴリ:C#
【環境】

 OS:Windows 7 64bit
 VS:Visual Studio 2008 SP1
 言語:C++,C#

 C#から,C++(32bit)で作成したDLLを呼び出し

【エラー】

C#のプログラムを実行したところ,C++の関数を呼び出す部分で下記のエラー発生。

vshost32.jpg

呼び出し部分のコードはこちら。

C#:あるクラスの中の1関数
private string getName()
{
 string name = DllWrapper.dllGetName();
 return name;
}

C#:DLLラッパークラス
namespace DllWrapperSpace
{
 public class DllWrapper
 {
  [DllImport("dllTest.dll")]
  public static extern string dllGetName();
 }
}

* dllTest.dll:C++のDLLの名前

C++:クラス
class TestDll
{
 private:
  char _name[1024];

 public:
  char* getName()
  {
   return _name;
  }
};

C++:DLL出力用のコード
TestDll test;
extern "C"
{
 __declspec(dllexport) char* WINAPI dllGetName()
 {
  return test.getName();
 }
}

【原因】

C++のDLL関数の戻り値char* を,C#でstring として宣言したことが原因

C#では,戻り値をstringとして宣言した場合,マーシャリングにより自動的にC++のchar*が参照しているメモリを解放するとのこと。
おそろしや・・・

  相互運用マーシャリング

【対策】

C#の戻り値をstringからIntPtrへ。
IntPtrをPtrToStringAnsiでstringへ変換。
ちなみに,PtrToStringAutoでは文字化け。
OSが64bitだからか!?,AutoにするとC++からUnicodeで文字列を受け取っていると勘違いするらしい。

呼び出し部分のコードはこちら。

C#:あるクラスの中の1関数
private string getName()
{
 IntPtr namePtr = DllWrapper.dllGetName();
 string name = Marshal.PtrToStringAnsi(namePtr);
 return name;
}

C#:DLLラッパークラス
namespace DllWrapperSpace
{
 public class DllWrapper
 {
  [DllImport("dllTest.dll")]
  public static extern IntPtr dllGetName();
 }
}

これで解決♪

【おまけ】

今回のコードでは,戻り値として文字列を受け取ったが,引数として文字列を受け取ることも可能。
その場合には,C++の引数はchar*C#の引数はStringBuilderとすればOK。





お気に入りの記事を「いいね!」で応援しよう

最終更新日  2010年02月10日 17時35分31秒
コメント(0) | コメントを書く
[C#] カテゴリの最新記事



© Rakuten Group, Inc.
X