私はここで非常に具体的な問題を抱えていますが、これは私の実践では見られません。私が間違っていることを示すのを手伝ってくれることを願っています:
したがって、2 つの C-sharp コンソール アプリケーションと、共有メモリ セグメントを持ち、データ (つまりステータス ビット) 交換に使用される 1 つのライブラリがあります。
ライブラリでは(簡単にするために、完全なコードを投稿することはできません。もう少しのものがあります)、次のようになります。
#pragma data_seg("shared")
int hbStatus = 0;
bool hbExit = false;
#pragma data_seg()
#pragma comment(linker, "/SECTION:shared,RWS")
extern "C" __declspec(dllexport) void __stdcall SetHBStatus(int status)
{
hbStatus = status;
}
int GetHBStatus()
を返す同様のものhbStatus
と、getter と setter のhbExit
1 つ
メイン アプリケーション (「マスター」という名前) では、このようにステータス ゲッターと終了セッターがインポートされます。
class Program
{
const string dllimport = @"interchange.dll";
[DllImport(dllimport)]
public static extern int GetHBStatus();
[DllImport(dllimport)]
public static extern void SetHBExit(bool value);
...
スレーブ アプリケーション (HB.exe) がインポートされSetHBStatus
、GetHBExit
次のロジックがあります。
static void Main(string[] args)
{
Initialize(); //after initialize, SetHBStatus is set to 1 if succeed, otherwise -1
InitializeHeartbeatTimer(); //timer period is set in initialize and thorows an events, which doing main logic, so we may have empty while cycle
while (!GetHBExit()) { }
Console.WriteLine("HB exit status: " + GetHBExit());
Console.ReadLine();
Deinitialize();
hbTimer.Dispose();
このステータスは、マスター アプリが続行するために使用されます。
Console.ForegroundColor = ConsoleColor.Green;
Console.WriteLine("SUCCESS!");
Console.ForegroundColor = ConsoleColor.Yellow;
Console.WriteLine("Invoking heartbeat application");
try
{
Process.Start(System.AppDomain.CurrentDomain.BaseDirectory + "\\HB.exe");
}
catch (Exception e)
{
Console.ForegroundColor = ConsoleColor.Red;
Console.WriteLine("Failed to invoke HB application. Ending...");
Console.WriteLine("Message: " + e.Message);
break;
}
Console.ForegroundColor = ConsoleColor.Green;
Console.WriteLine("SUCCESS!");
SetHBExit(false); //clearing junk in library, if any
Console.ForegroundColor = ConsoleColor.Yellow;
Console.WriteLine("Waiting for HB app initializes");
while (GetHBStatus() == 0) //waiting for response HB.exe
{ }
if (GetHBStatus() > 0)
{
Console.ForegroundColor = ConsoleColor.Green;
Console.WriteLine("SUCCESS! Heartbeat send and ticking by interval");
}
if (GetHBStatus() < 0)
{
Console.ForegroundColor = ConsoleColor.Red;
Console.WriteLine("HB application fails. Check HB_log.txt for more details. Ending...");
break;
}
Console.ForegroundColor = ConsoleColor.Yellow;
Console.WriteLine("Generating file for.....
...
そして、HBアプリケーションにそれ自体を初期化解除して強制終了するように指示する必要がある場合は、マスターから呼び出します。この呼び出しは1か所でのみ実行していますが、問題があります(hbStatus
ライブラリには「1」フラグがあり、Deini
tは設定されています)hbStatus
次のように、マスターを期待しています:
Console.ForegroundColor = ConsoleColor.Yellow;
Console.WriteLine("Disconnecting heartbeat");
SetHBExit(true);
while (GetHBStatus() > 0) { }
Console.ForegroundColor = ConsoleColor.Green;
Console.WriteLine("HB killed and disconnected");
Console.WriteLine("\nAll disconnected, invoking main menu");
ShowOptions();
そして今、私の問題です: マスター アプリケーションを実行すると、HB.exe が呼び出され、初期化されます。HB は成功フラグを返し、マスターは通常の作業を続行しますが、HB は Deinit で突然終了し、Exit フラグを受け取ったときにそれ自体を閉じます。ただし、フラグ NOTHING および NOBODY は、適切な関数を呼び出すことによって設定されます (切断と強制終了に関するメッセージは表示されません)。
SetHBExit を HB.exe にインポートしようとして、初期化後に false で呼び出すと、まだ問題が発生します。
これは 32 ビットのアプリケーションとライブラリでのみ見られます。これを 64 バージョンにコンパイルすると、アプリケーションはスムーズに動作し、必要に応じて適切に動作します。しかし、アプリケーションは64バージョンで実行できないクライアント用であるため、64ビットバージョンを使用できません(これも奇妙な問題です。彼は64ビットでW7を持っていますが、プログラムが最初に呼び出しを試みているときにBadImageFormatExceptionを受け取りますライブラリ関数 (私のマシンでは正しく動作します。奇妙な、奇妙な)
私が間違っている提案はありますか?