Search code examples
c++jsoncommand

'Invalid memory access' while reading json file from another project


I have a dll in C++ which is used for behaving like smartcard. I wrote a JSON file for receiving data and responsing wanted response. It looks like this:

{
    "00xxxxxx" : ["aaaaaaaaaaaaaaaaa", {
        "00yyyyyyyyyy" : ["bbbbbbbbbbbbbbbb", {
            "00zzzzzzzzz" : ["9000", {}]
        }]
    }]
}

My CommandHandler.cpp file receiving the command from another application. It looks like below:

string CommandHandler::sendCommand(string command)
{
    data = data[command];
    string response;    
   
    if(data == nullptr){
       response = "6700";
       return response;
    }
    response = data[0];
    data = data[1]; 

    return response;
}

CommandHandler::CommandHandler(){} //Empty constructor

 
CommandHandler::CommandHandler(string jsonCommandsPath)
{
    std::ifstream f(jsonCommandsPath);
    data = json::parse(f);
}
string CommandHandler::getJsonFile(){
    jsonCommandsPath = "MyPath";
    return jsonCommandsPath;
}

And lastly, I call CommandHandler constructor in another class named FakeTransmitter.cpp:

CommandHandler command;
NOT_EXPORTED CommandHandler commandHandler(command.getJsonFile());

EXPORTED LONG CardTransmit(CARDHANDLE hCard,
                    LPCBYTE pbSendBuffer, DWORD cbSendLength,
                    /*@out@*/ LPBYTE pbRecvBuffer, PDWORD pcbRecvLength) {
                        string command = Conversion::ByteArrayToHexStr(pbSendBuffer, cbSendLength);
                        
                        string response = commandHandler.sendCommand(command);
                        //here I wrote response code, it works correctly.
                        return 5; 
                    }

I build this project with CMake and use the dll in another project for fake response. However, in the first call the commands it works, after I call the same commands, it returns '6700' which means it returns nullptr.

The output of the second project looks like this:

Command: 00xxxxxx
Response: aaaaaaaaaaaaaaaaa
Command: 00yyyyyyyyyy
Response: bbbbbbbbbbbbbbbb
Command: 00zzzzzzzzz
Response: 9000
Command: 00xxxxxx -------> Here I call first command again in the same runtime
Response: 6700

I think, I can not read that JSON file again. How can I reach the same command while I call from the second project?

I just want that while I call the same commands again, I show the response. The output that I expected should look like this:

Command: 00xxxxxx
Response: aaaaaaaaaaaaaaaaa
Command: 00yyyyyyyyyy
Response: bbbbbbbbbbbbbbbb
Command: 00zzzzzzzzz
Response: 9000
Command: 00xxxxxx
Response: aaaaaaaaaaaaaaaaa
Command: 00yyyyyyyyyy
Response: bbbbbbbbbbbbbbbb
Command: 00zzzzzzzzz
Response: 9000

I already tried f.close() and f.open() in the project. Maybe I used them wrong but while I used them it returns me 'Invalid memeory acces'. Is there a solution to handle this problem?


Solution

  • So it seems to me that you want the original JSON structure to be reused when you receive a command that cannot be understood with the current JSON structure. So to do that you need to first save the original JSON structure in your class

    CommandHandler::CommandHandler(string jsonCommandsPath)
    {
        std::ifstream f(jsonCommandsPath);
        originalData = json::parse(f);     // save the original data
        data = originalData;               // and start with the original data
    }
    

    You will need to add originalData to your CommandHandler class. Because you didn't show that class I can't tell you how to do that, but hopefully it's clear enough.

    Then you need to reuse that original data when you find a command that cannot be understood.

    string CommandHandler::sendCommand(string command)
    {
        data = data[command];
        string response;    
       
        if(data == nullptr){
           data = originalData;         // restore the original data
           return sendCommand(command); // and try again
        }
        response = data[0];
        data = data[1]; 
    
        return response;
    }
    

    I am guessing somewhat because your requirements are not completely clear.