私は友人の学士論文プロジェクトを手伝っています。様々な材料の曲げモーメントを計算するプログラムです。クライアントが望む追加の要件の 1 つは、プログラムで使用されるさまざまなデータを格納および取得するためのデータベース機能です。
このプログラムは、マネージ C++ で作成されたフォーム アプリケーションです。私はデータベース機能の作成を手伝うために参加しました。プログラムとデータベースを橋渡しするために、MySQL Server 5.5 と MySQL Connector/C++ を使用しています。すべてが順調に進んでおり、必要なすべての機能は問題なく動作しますが、デバッグのみです。プログラムをリリース モードにするとすぐに、実行時に未定義の動作が発生します。以下は、データベースへの接続を開くために使用される関数です。
try
{
m_driver = get_driver_instance();
m_conn = m_driver->connect(m_dbHost, m_dbUser, m_dbPwd);
m_conn->setSchema(m_dbSchema);
}
catch(sql::SQLException &e)
{
int a = e.getErrorCode();
MessageBoxA(NULL, e.what(), "DB Error", MB_OK);
}
connect 関数に渡される値はすべて std::string です。デバッグ モードでは、接続は問題なく行われます。リリース モードでは、接続関数が呼び出された後に例外がキャッチされ、「Unknown MySQL Server Host '####' (0)」というメッセージが表示されます。ここで、#### は常に何らかのガベージ テキストです。また、出力ウィンドウで別の例外がスローされていることにも気付きました。これは System.Runtime.InteropServices.SEHException 型です。
私はいくつかの調査を行っており、多くのフォーラム (およびここではスタック交換) でこの例外の多数のケースを見てきましたが、MySQL コネクタでこの問題が発生しているようには見えません。プログラムが混合モードであり、メイン プログラム コードがマネージ C++ で記述され、データベース ヘルパー コードがネイティブ C++ で記述されているため (コネクタの必要に応じて)、メモリが破損していると推測されます。
コードを変更して、実行時に文字列が破損しないようにこの問題を修正できるものはありますか? 問題を解決するためにさまざまなハックを試しましたが、何も機能しませんでした。
ありがとう、トム
更新: デバッグ モードでこのエラーが表示されるようになりました。データベースから値を取得し、フォームにいくつかのテキスト ボックスを入力するコードを追加しました。コードは次のとおりです。
// Populate the form with material details
String^ selectedMaterial = (String^)(comboBox1->SelectedItem);
string selectedMaterial_ = "";
MarshalString(selectedMaterial, selectedMaterial_);
sql::ResultSet* results = dbHelper.GetData("matname", selectedMaterial_);
if (results->rowsCount() == 1)
{
// Outdim
string outdim_ = "";
outdim_ = results->getString("outdim");
String^ outdim = gcnew String(outdim_.c_str());
textBox1->Text = outdim;
}
else
{
// !!!! Duplicate materials in list
}
結果セットから outdim を読み取ろうとすると、SEHException がスローされます。他に提供される唯一の情報は、それが外部コンポーネントでスローされたということです。
更新 2: デバッグ実行可能ファイルに対して Application Verifier を実行し、VS2010 からプログラムを起動しました。ただし、フォーム ウィンドウがロードされないため、プログラムがどこかで停止している必要があります。奇妙なことに、Application Verifier のログ ファイルにはまったく情報がありません。リリース版も試してみましたが、そこからも有用な情報は得られませんでした。