C++ DLL not working when used inside Experimenter (works fine outside)

C++ DLL not working when used inside Experimenter (works fine outside)

roger_salaT7YTD
Observer Observer
216 Views
4 Replies
Message 1 of 5

C++ DLL not working when used inside Experimenter (works fine outside)

roger_salaT7YTD
Observer
Observer

 

Hello everyone,

 

I’m currently developing a custom C++ DLL to improve the performance of a Dijkstra algorithm that calculates shortest paths in my FlexSim model. The DLL returns an array of size 2: the route to follow and its corresponding weight.

 

Previously, we used an external Python script for this purpose, and it worked correctly both inside and outside of the Experimenter. After switching to the C++ DLL implementation, the code still runs perfectly when I execute the model directly, but it stops working when executed through the Experimenter. It doesn’t crash — it simply returns an empty array, and then each scenario logically fails.

 

Diagnosing the issue has been difficult because the DLL doesn’t seem to write any logs while running inside the Experimenter (I might be doing something wrong here). I’ve also confirmed that the “Apply the following scenario and replication to the model?” option confirms the error. Interestingly, when I try to debug a failed scenario from the Experimenter in the model directly, the model starts working normally again.

 

My questions are:

- Does the Experimenter fully support the use of external C++ DLLs in this way?

- Could this be related to threading or memory-safety issues within the Experimenter’s environment?

- Are there any common pitfalls or recommended debugging approaches for DLLs used in Experimenter runs?

 

I’d also appreciate any advice on how to effectively log or debug code that runs inside the Experimenter, since traditional file logging seems to fail there.

 

Any suggestions or insights would be greatly appreciated. For context: I’m still relatively new to both FlexSim and C++.

 

Thanks in advance!

 

Environment details:

FlexSim version: 25.1
Build configuration: Release (x64)
Runtime library: Multi-threaded DLL (/MD) (also tested with /MT)
Exceptions: Enabled (/EHsc)
C++ standard: ISO C++20 (/std:c++20)
Platform Toolset: Visual Studio 2022 (v143)

0 Likes
217 Views
4 Replies
Replies (4)
Message 2 of 5

joerg_vogel_HsH
Mentor
Mentor

Single run vs. experimenter

An experiment runs simultaneously parallel to other experiments. If your DLL does not take into account that it can run in multiple instances then it isn’t suited for experiments. If your log is a static file, then this is a problem. 

Message 3 of 5

roger_salaT7YTD
Observer
Observer

Thanks for your response Jörg,

 

However, I still have some unresolved doubts that were also included on my question:

 

- Could this be related to threading or memory-safety issues within the Experimenter’s environment?

- Are there any common pitfalls or recommended debugging approaches for DLLs used in Experimenter runs?

 

Moreover, if you know where to find a model that uses a custom DLL to see how it's done, that would be very helpful.

 

Thank you in advance.

0 Likes
Message 4 of 5

logan_gold
Community Manager
Community Manager

Hi @roger_salaT7YTD, here is some information I have been able to gather about your situation and questions.

 

First, the Experimenter does support the use of external C++ DLLs.  The Experimenter works by creating multiple child instances of FlexSim to run the model with all the different scenarios set up in the Experimenter.  Each child instance should then each open the DLL separately.  You can test if there is an issue with having multiple instances of the DLL opened at once by opening the FlexSim software (normally) multiple times and running your model (normally) concurrently in all these instances.

 

Next, how are you building the C++ DLL?  Are you using the DLL Maker or developing a module?  If you are using the DLL Maker, then it can only return a double and not an array.  However, if that were the issue, I would think it would show up when running the model normally and not just in the Experimenter.

 

Another issue, though, is that recent versions of FlexSim (starting with 24.2 I believe) will display a security warning when trying to connect to an external C/C++ DLL and those DLLs can only be loaded if this warning is accepted.  This message will not display, and the DLL cannot be loaded, without a UI.  The Experimenter does not use a UI for the child processes, so it cannot load external DLLs created with the DLL Maker.  If this is the case, then you will need to use the Module SDK to create a module instead of the DLL Maker.

 

Another thing to try is to delay loading the DLL to make sure the child processes are fully loaded before the DLL tries to load.  In the DLL, there should be a dll initialize method that always happens.  Within this method, you can try adding a sleep command to wait for a few seconds before continuing and see if the DLL gets loaded when running the Experimenter.  Or you could try creating a test file and write some sort of test text from within this method.  If the file is not created or the text does not get written when running the Experimenter, then the DLL is not getting loaded at all with the child processes.

 

If you are able to perform any of these tests and they do not indicate what the issue may be, please let me know the results of your testing and we can go from there.

0 Likes
Message 5 of 5

roger_salaT7YTD
Observer
Observer

Hi @logan_gold ,

 

Thanks a lot for the insights!

 

"You can test if there is an issue with having multiple instances of the DLL opened at once by opening the FlexSim software (normally) multiple times and running your model (normally) concurrently in all these instances."

 

We have tested it and can confirm that it works.

 

We are building the DLL and using it through the External C++ Code User Command approach, as described in:

https://docs.flexsim.com/en/25.1/Reference/DeveloperAdvancedUser/ConnectingToExternalCode/Connecting...

The setup follows the environment configuration described in the first message, and we are compiling and building the solution using Microsoft Visual Studio 2022.

 

"then it can only return a double and not an array."

 

I'm really confused by this as we have managed to return pretty much any FlexSim Datatype, i.e double, int, string, array, Map in this way.

 

I'll add a few examples that I can show here:

 

__declspec(dllexport) Variant modifyMapExample(FLEXSIMINTERFACE)
{
    Variant mapVar = param(1);
    Map mp = mapVar;

    mp[5] = 123;
    mp["newKey"] = "hello";

    return mp;
}

__declspec(dllexport) Variant TestUserCommand(FLEXSIMINTERFACE)
{
    return "Hello World";
}

 

Yes, we do receive the security warning when attempting to connect to an external C/C++ DLL, and those DLLs can only be loaded once the warning is accepted.

I'm confused by this, if this warning appears, shouldn't the Experimenter theoretically pause and wait for the user to accept the security prompt—since without a UI, it shouldn’t be possible to bypass it. However, in our case, the Experimenter scenario finishes very quickly, without any errors related to the User Command that calls the DLL. When running inside the Experimenter, the function that relies on the DLL simply returns an empty array (which matches the expected data type of the result).

 

I’m having a lot of trouble debugging this. As I understand it, are you saying that this kind of DLL functionality (i.e to work inside of Experimenter) can only be achieved through Module Development?


"Another thing to try is to delay loading the DLL to make sure the child processes are fully loaded before the DLL tries to load. In the DLL, there should be a dll initialize method that always happens.
Within this method, you can try adding a sleep command to wait for a few seconds before continuing and see if the DLL gets loaded when running the Experimenter.
Or you could try creating a test file and write some sort of test text from within this method.
If the file is not created or the text does not get written when running the Experimenter, then the DLL is not getting loaded at all with the child processes."

 

 

We have tried creating such method and do not really understand the results. It does generate the file even when called from inside the experimenter but somehow it does nothing more. The code that works from outside of Experimenter still does not work as we mentioned in the previous posts. Moreover we can't seem to get any logs from outside of the initialize method

 

Thanks in advance!

 

 

0 Likes