0

私はここで非常に具体的な問題を抱えていますが、これは私の実践では見られません。私が間違っていることを示すのを手伝ってくれることを願っています:

したがって、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 のhbExit1 つ

メイン アプリケーション (「マスター」という名前) では、このようにステータス ゲッターと終了セッターがインポートされます。

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) がインポートされSetHBStatusGetHBExit次のロジックがあります。

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」フラグがあり、Deinitは設定されています)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を受け取りますライブラリ関数 (私のマシンでは正しく動作します。奇妙な、奇妙な)

私が間違っている提案はありますか?

4

1 に答える 1

0

更新と可能な解決策:

「古い」C は「bool」型をそのままサポートしていません。typedef int である BOOL を使用すると、32 ビット アプリケーションは正しく動作します。だから私はこの問題を解決したと考えています:)

64 ビット マシン上の 64 ビット アプリケーションの二次的な問題は未解決のままです。BadImageFormat 例外が発生しますが、私のマシンでは問題なく動作します。

于 2013-02-11T13:17:52.000 に答える