単純な C++ ラッパー クラスを呼び出す C# アプリケーションがあり、それが既存の C++ DLL を呼び出します。C++ コードはすべて VC++ 6.0 です。
一貫性のない動作が得られますが、クラッシュが発生した場合、クラッシュは常に C++ ラッパー DLL 内で発生し、常に同じ場所で発生します (苦痛なログ ステートメントを使用して確認しました)。Windows 2008 以外の環境では発生しないため、何らかの理由で Windows 2008 がより注意を払っていることに、致命的ではないものの悪いメモリの破棄が行われていると思われます。
関連するコードは次のとおりです。これがクラッシュする理由について誰かが考えている場合は、大歓迎です。私たちは数日間頭を悩ませてきましたが、プロジェクトのタイムラインは、単純な文字列を C# に戻すことができるようにするために遅れています...
VariantInit を使用して VARIANT vresult を設定し、VariantClear を使用した後にそれをクリアしようとしたと言われましたが、それは役に立ちませんでした。
// JobMgrDll.cpp : Defines the entry point for the DLL application.
//
#include "stdafx.h"
#include "JobMgrDll.h"
#include "jobmgr.h"
CString gcontext;
CString guser;
CString ghost;
CString glog;
JOBMGRDLL_API int nJobMgrDll=0;
extern "C" JOBMGRDLL_API char* perform_billcalc(char* cmd, char* context, char* user,char* host,BSTR* log,int* loglen)
{
char* result = new char[1000];
memset(result,0,999);
result[999] = '\0';
bstr_t bt_command = cmd;
UUID uuid = __uuidof(BRLib::Rules);
VARIANT vresult;
char *p_rv;
gcontext = context;
guser = user;
ghost = host;
write_log("execute_job");
p_rv = execute_job(uuid, "none", bt_command, &vresult);
write_log("DONE execute_job");
CString message;
write_log ("Intializing bstr_t with variant"); // WE ALWAYS GET HERE
bstr_t res(vresult);
//message.Format("%s result = %s",p_rv,res);
//write_log(message);
write_log("copying Result"); // WE DON'T ALWAYS GET HERE, BUT SOMETIMES WE DO
strcpy(result,(char*)res);
write_log(CString(result));
*loglen = glog.GetLength();
*log = glog.AllocSysString();
return result;
}
繰り返しになりますが、どんなアイデアでも大歓迎です。