0

ちょっと変な状況。サードパーティのアプリに挿入して情報を取得するために作成された C++ dll があります。この dll はもともと情報を出力するだけでしたが、作成した VB アプリで使用する必要がありました。

そこで、元の C++ dll から 2 つのコールバック関数を持つ別の C++ dll を作成しました。ここに情報が送信されます。また、VB アプリがその情報を取得するために呼び出すことができる関数があります。

私は C++ があまり得意ではありません..しばらくこれをいじっていて、クラッシュの発生を減らしましたが、それでも発生します (非常にまれですが)。ある時点で、クラッシュの原因となる同じアドレスに対して 2 つの異なる部分が読み取りまたは書き込みを行っていると思います。コードは次のとおりです。

これは、コールバック関数からの情報を保存し、VB に送信するために使用するグローバル cstring です。

class Global
{
public:

    static CString &  get_allstacks() {
        static CString allstacks; return allstacks; }
};

これは、情報を送信する VB から呼び出す関数です。

BSTR _stdcall vbFunction()
{
    BSTR Message;
    int len = Global::get_allstacks().GetLength();
    Message = SysAllocStringByteLen ((LPCTSTR)Global::get_allstacks(), len+1 );
    return Message;

}

これはコールバック関数の 1 つです。情報を同じグローバル cstring に入れる別の関数もあります。この関数では、長さが 100k を超えると cstring のサイズも変更されます。サイズ変更コードはコールバックの 1 つだけにあることに注意してください。

HANDLE OnInfo(SendInfo* info)
{
    strcpy_s(tempID,200,info->GameId);
    CString stringTempID="";
    stringTempID=tempID;

    CString tempRound="";
    strcpy_s(round,200,info->round);
    tempRound=round;

    // get a reference to global string
    CString & allstacks= Global::get_allstacks();
    // add new info
    allstacks+=  stringTempID + tempRound + "\n";

    //resize cstring
    int len =allstacks.GetLength();
    if  (len > 100000)
    {
        int nstart = 0;
        int npos  = 0;

        while ((npos = allstacks.Find(_T('\n'), nstart)) < len - 50000) {
            nstart = npos+1;
        }   

        allstacks= allstacks.Right(nstart);
    }

    return 0;
}

これが必要な場合

char* tempID =new char[255];
char* round=new char[255];

とにかく、クラッシュは非常にまれです。 vbFunction が呼び出されたときに数回発生しましたが、大部分は vbFunction が呼び出されずに発生したため、問題はコールバック関数でも発生していると思います。

4

0 に答える 0