c++serverplcopc-uaopen62541

"... .exe hast stopped working" only occurs at my friend's computer but not on mine


I'm having a problem with the release version of my program. When I start it on my computer, everything works fine. There are no exceptions, no problems or any other stuff that stops me from working with the program. As soon as I zip the exe and its required DLLs and send it to a friend, he instantly receives the error ".exe has stopped working" when he tries to run the server.

By the way it's an opc server built with "open62541". When running, it retrieves values out of a PLC by the use of a library called "Snap7". And yes, he's located in the same network as I am, hence the reason cannot be the network connection.

We both are using windows and my IDE is Visual Studio 2015. Unfortunately, I cannot really post any code here because it's way too much. Moreover I wouldn't really know which code to post since I don't know where and why the error comes up.

EDIT: Here's my code where I get the exception. It's always thrown when "UA_Server_addVariableNode" is called.

for (int i = 0; i < 4; ++i)
{
    UA_VariableAttributes attrAttr;
    UA_VariableAttributes_init(&attrAttr);
    UA_QualifiedName attrBrowseName;
    UA_QualifiedName_init(&attrBrowseName);

    switch (i)
    {
    case 0: //Setting the ip-address
        UA_Variant_setScalar(&attrAttr.value, &UA_STRING(currentPlc.ip), &UA_TYPES[UA_TYPES_STRING]);
        attrAttr.displayName = UA_LOCALIZEDTEXT("en_US", "IPAddress");
        attrBrowseName = UA_QUALIFIEDNAME(1, "IPAddress");

        //Add the PLC value to the PLC-ObjectType
        UA_Server_addVariableNode(server, UA_NODEID_NULL, newPlcId,
            UA_NODEID_NUMERIC(0, UA_NS0ID_HASCOMPONENT),
            attrBrowseName,
            UA_NODEID_NULL, attrAttr, NULL, &isAvailableNodeId);
        break;

    case 1: //Setting the rack
        UA_Variant_setScalar(&attrAttr.value, &currentPlc.rack, &UA_TYPES[UA_TYPES_INT32]);
        attrAttr.displayName = UA_LOCALIZEDTEXT("en_US", "Rack");
        attrBrowseName = UA_QUALIFIEDNAME(1, "Rack");

        //Add the PLC value to the PLC-ObjectType
        UA_Server_addVariableNode(server, UA_NODEID_NULL, newPlcId,
            UA_NODEID_NUMERIC(0, UA_NS0ID_HASCOMPONENT),
            attrBrowseName,
            UA_NODEID_NULL, attrAttr, NULL, &isAvailableNodeId);
        break;

    case 2: //Setting the slot
        UA_Variant_setScalar(&attrAttr.value, &currentPlc.slot, &UA_TYPES[UA_TYPES_INT32]);
        attrAttr.displayName = UA_LOCALIZEDTEXT("en_US", "Slot");
        attrBrowseName = UA_QUALIFIEDNAME(1, "Slot");

        //Add the PLC value to the PLC-ObjectType
        UA_Server_addVariableNode(server, UA_NODEID_NULL, newPlcId,
            UA_NODEID_NUMERIC(0, UA_NS0ID_HASCOMPONENT),
            attrBrowseName,
            UA_NODEID_NULL, attrAttr, NULL, &isAvailableNodeId);
        break;

    case 3: //Setting "isAvailable" to give information about the PLC's status
        UA_Variant_setScalar(&attrAttr.value, &isAvailable, &UA_TYPES[UA_TYPES_BOOLEAN]);
        attrAttr.displayName = UA_LOCALIZEDTEXT("en_US", "isAvailable");
        attrBrowseName = UA_QUALIFIEDNAME(1, "isAvailable");

        //Add the PLC value to the PLC-ObjectType
        UA_Server_addVariableNode(server, UA_NODEID_NULL, newPlcId,
            UA_NODEID_NUMERIC(0, UA_NS0ID_HASCOMPONENT),
            attrBrowseName,
            UA_NODEID_NULL, attrAttr, NULL, &isAvailableNodeId);
        break;
    }
}

Solution

  • I solved the problem after doing some research inside the "open62541" header.

    In case 0 I use the expression "&UA_STRING(currentPlc.ip)" in the "UA_Variant_setScalar" function which I thought returns the equivalent UA_String of "currentPlc.ip".

    But it actually returns a temporary object that is deleted after the function is called. As a result, the actual address of the object is null, hence I get an access violation. I simply added one line in which I pass the returned object to a variable and then use the address of the variable.

    case 0: //Setting the ip-address
            auto value = UA_STRING(currentPlc.ip);
            UA_Variant_setScalar(&attrAttr.value, &value, &UA_TYPES[UA_TYPES_STRING]);
            attrAttr.displayName = UA_LOCALIZEDTEXT("en_US", "IPAddress");
            attrBrowseName = UA_QUALIFIEDNAME(1, "IPAddress");
    
            //Add the PLC value to the PLC-ObjectType
            UA_Server_addVariableNode(server, UA_NODEID_NULL, newPlcId,
                UA_NODEID_NUMERIC(0, UA_NS0ID_HASCOMPONENT),
                attrBrowseName,
                UA_NODEID_NULL, attrAttr, NULL, &isAvailableNodeId);
            break;