ATTENTIONThis FlexSim Community Forum is read-only. Please post any new questions, ideas, or discussions to our new community (we call it Answers) at https://answers.flexsim.com/. Our new Question & Answer site brings a modern, mobile-friendly interface and more focus on getting answers quickly. There are a few differences between how our new Q&A community works vs. a classic, threaded-conversation-style forum like the one below, so be sure to read our Answers Best Practices. |
flexsim.com |
#21
|
||||
|
||||
Hey Steven,
If you're declaring a flexsim-accessible function in a dll, the function must be declared exactly as: Code:
visible double functionname ( FLEXSIMINTERFACE ); Code:
typedef void (*_stringreturn)(char *instr, _callpoint *cp); Code:
DECLARE_FLEXSIM_FUNCTION(stringreturn) Code:
stringreturn(thestringtoreturn, callpoint); return 0; To do this in flexscript, you can just return the string directly, whether it be a string literal, a call to a function, or a global or local variable. Code:
return "hello"; return getthestringfromafunction(); Last edited by Anthony Johnson; 03-20-2009 at 09:19 AM. |
The Following 3 Users Say Thank You to Anthony Johnson For This Useful Post: | ||
Ramesh Pinn (05-17-2013) |
#22
|
||||
|
||||
Quote:
I thought about user commands which connect the dll and his functions with flexsim to prevent compiling. But how can I pass an array from flexsim to dll and backwards? Thanks |
#23
|
||||
|
||||
Carsten,
I don't think that you can pass an array directly, because on the DLL side you only have the parnode, parval and parstr command to get the parameters out. You can use global variables from within the DLL although I haven't tested it, so a global array should be possible. Other option is that you use a node structure as an array and pass in the main node as a parameter. (or use a table for that matter) Or you create a flexscript function that gets or sets a value from the array and call that function from within the DLL with nodefunction. That is what I can think of for the moment. Steven |
The Following User Says Thank You to Steven Hamoen For This Useful Post: | ||
Carsten Seehafer (03-18-2009) |
#24
|
|||
|
|||
I've got an external DLL and can now successfully call into it with integers, doubles, and strings. I can also get the DLL to return integers and doubles, but I'm still having problems getting it to return a string. I tried what Anthony Johnson suggested in his 20 Feb 2009 post (actually it was already in the version of FlexsimDefs.h and FlexsimFuncs.h that I downloaded).
But when I try this, I get a runtime error from Flexsim when that function executes saying, "A dll attempted to call a Flexsim function that could not be bound. Unsuccessful Bindings: ....". It then lists a bunch of what appear to be commands. The error is definitely tripping up on the stringreturn("xyz", callpoint); that I have right before the return(0); statement in the DLL. Within the Flexsim model, the function is called on a trigger with, string retval = DLL_strings(current, 1, 2, 3); , which is calling a User Command that's toggled to DLL. Everything else is working right...if I comment out the stringreturn(..) line in the DLL, everything executes as expected...well, except that it returns a NULL string. Thoughts? Thanks, David White |
#25
|
|||
|
|||
Anthony,
Actually, after looking around, I think what I really want to use is the COM object that you created (/downloadPages/file&id=180)). I think this does what I need, but I do have a few questions. This could be very powerful and useful if Flexsim had the time to fill it out all the way and write up the documentation. 1. How does the FlexsimRPC.fsm get loaded? Does that get loaded first when you call the openmodel() method? It looks like that simply loads the FlexsimRPC.fsl and copies over the RPCManager object to the Tools node of model that was opened. 2. It doesn't copy over the usernotifycom object that's next to the RPCManager (of course that object is empty anyway)....does that mean the OnUserNotify event isn't installed and working yet? 3. There's no methods to "setup" the OnUserNotify event...so how's that work? Can I just add a FlexsimApp_OnUserNotify function in my host? What parameters comes in on that and what triggers it? 4. Related to .html#3, if I want an event (such as OnConveyEnd) to poke my host, can I put something in the model that will do that? Since the RPCManager isn't loaded until run time, I'm assuming that adding code to an event trigger to cause a OnUserNotify event would confuse Flexsim as I make a model??? Help? 5. What's the getinterfacename method do? 6. What's the second parameter in the SetUpdateInterval method do? I noticed a switch/case statement in the OnTimerEvent in the RPCManager...is that for that? 7. What were to happen if the host were to call the Stop method asynchronously? For instance, you call the Stop method during the OnNotificationTime event...so Flexsim is at a "good" stopping point then. But if Flexsim is chunking along and the Stop method gets called while it's mid-processing on a time slice, could that mess things up? I presume it's no different than hitting the stop button normally, but I just want to make sure. We've been using Flexsim for development of a new product that has lots of interacting hardware. And so far, we've been using it in the normal fashion that it was intended. But now, we're wanting/hoping to use Flexsim to actually simulate the hardware during development of the controlling software. For instance, the sw group can write/test their code....interfacing the simulated hardware thru the COM object. Then when the real hardware is ready (which could be a year or so), an interface layer of software can be substituted in for the COM object and everything should work! But to do this, we obviously need the Flexsim to act like the real hardware will, which includes having it send messages to the controlling software on trigger events, which is why question #4 is critical. Also, whatever host I choose to run the FlexsimAXApp on (probably will be a dialog-based c# program) would allow us to simulate an operator on the floor pushing buttons, loading objects, interacting with the hardware, etc., and that would go thru the COM interface to affect the model's behavior within Flexsim. Does this make sense? We want our controlling software that we're developing to be able to go in and affect the model while it's running, and have the model send messages to the controlling software as things happen. 8. Does this sound do-able? Do you think there's enough in your first cut of the COM object to pull this off? Thanks very much, David White |
#26
|
|||
|
|||
Oh.... just found the answer to 3 and 4.
Event OnUserNotify(ByVal p1 As Double, ByVal p2 As Double, ByVal p3 As Double, ByVal p4 As Double, ByVal p5 As Double, ByVal p6 As Double, ByVal p7 As Double, ByVal p8 As Double, ByVal p9 As Double, ByVal p10 As Double, returnval As Double) As Double Member of FlexsimAXDLLLib.FlexsimAXApp method OnUserNotify : fires whenever the model calls a special flexsim command called usernotifycom(). Designed to let the model builder notify com clients at any time in the model. Sorry I didn't notice that in the Object Browser before the above post. But I'd still like your opinion overall on what I'm trying. Thanks, David White |
#27
|
|||
|
|||
Ok. I have a c# app running that kind of works. I have all the methods on buttons. The StartApplication method starts up Flexsim and ExitApplication closes Flexsim. So I'm pretty sure my hooks are right. But when I try to OpenModel (after StartApplication of course), it just hangs. I can see that Flexsim still has the FlexsimRPC.fsm model open and never changes to the one I specify (FlexsimRPCTest.fsm). I've stepped thru the code and know that it's sending a good string...full path. I even copied it to c:\FlexsimRPCTest.fsm and tried it there thinking that maybe the space in Program Files was causing problems. Nothing. Flexsim never changes to the new test model and my host app quits responding.
Thoughts on that? Thanks, David White |
#29
|
|||
|
|||
Steven,
You're on the right track.... It looks like the *something* is stripping the "\\"'s out of the string....entirely. If my input string to OpenModel is "c:\\FlexsimRPCTest.fsm", it doesn't work...but I noticed that if you minimize/maximize Flexsim while it's hung up during this, the title banner changes to "c:FlexsimRPCTest.fsm". So I made my input string "c:\\\\FlexsimRPCTest.fsm", and it works. Similarly, "C:\\Program Files\\Flexsim4\\libraries\\FlexsimRPC\\FlexsimRPC Test.fsm" doesn't work (hangs), but, neither does "C:\\\\Program Files\\Flexsim4\\libraries\\FlexsimRPC\\FlexsimRPC Test.fsm"....this at least generates an error that say it can't find the file "C:\Program FilesFlexsim4librariesFlexsimRPCFlexsimRPCTest.fsm ". So, if I replace all the "\\"'s with "\\\\"'s, changing the input string to "C:\\\\Program Files\\\\Flexsim4\\\\libraries\\\\FlexsimRPC\\\\Fl exsimRPCTest.fsm"...then it works. This is regardless of whether the input to OpenModel is a string variable or a literal. This is odd because the Excel example that Anthony made doesn't have double-double backslashes... So I would have to assume the OpenModel method itself isn't removing the backslashes. But when I'm using a literal in the call, that goes straight into the .NET framework, so I don't think anything on my side would be removing them. In fact, if something was specifically removing backslashes, it would remove all of them...my doubling them up wouldn't have worked. Odd. Incidentally, it would be nice if OpenModel returned a success/failure value. When it says it couldn't find/load the file, my software can't realize that and do something about it. Anyway, it's up and running now. Going to play with the OnUserNotify next. Thanks, David White |
#30
|
|||
|
|||
Hi David,
I know that you have gone for a different approach but I did a check regarding your problem with Code:
stringreturn("xyz", callpoint); Are you sure that your are using the latest version from Google Code? If yes, I can not see whay it should not work. Lars-Olof |
#31
|
|||
|
|||
Yeah, pretty sure I am.
However, I have an update with the c# app I'm writing. (I'll try to post the project tomorrow). I'm still using the FlexsimRPCTest.fsm project for testing/debugging. I have most everything working. I can change lables, invoke functions while the model is running, I can change the period of the OnUpdateInterval on the fly too. I changed the function that sets the number of operators a little and moved it to a User Command, so I can change the number of operators up and down on the fly while the model's running too. I didn't quite get to the OnNotificationTime yet, but I should have that by tomorrow. I lost a lot of time trying to figure out why the OnUserNotify isn't working. Still haven't figure that out. And for my ultimate goal, that's the important one. Since I'm getting the OnUpdateInterval events, I'm pretty sure the hooks are right...but it just never gets called. In the OnExit trigger of one of the processors I have it call usernotifycom(). I have it print out a debug msg to the OutputConsole, so I know it's executing. I can't actually find the usernotifycom() function in the model. I know it's there because after it's been loaded by the RPCManager, it's blue and hovering over it gives you the parameters in a tool tip. But I can't find it. If I load FlexsimRPC.fsm manually, I can see it as a User Command...it simply calls a function in a FlexsimServer.dll. So. Has anybody tried the OnUserNotify with anythinng they've done yet? If I get the OnNotificationTime event working tomorrow and still can't get the OnUserNotify, I'm going to have to assume it's not working on the Flexsim side. Does anyone know if Anthony Johnson still works for Flexsim? Thanks, David White |
#33
|
|||
|
|||
It's too bad Anthony is busy...I'm sure he could weigh in on this pretty good. I'm not sure what day next week we have to make a decision on whether we can use this concept...maybe he'll have a chance early next week.
I have everything working except the OnUserNotify. Here is the Visual Studio C# project with all the source code. I modified the FlexsimRPCTest.fsm slightly (included in zip but named FlexsimRPCTest_mod.fsm). Basically I only changed where the function that sets up the number of operators is and I added the call to usernotifycom() in the top processor's (Processor 3's) OnExit trigger. Here's the file (http://www.flexsim.com/community/for...do=file&id=222). If I can't get the OnUserNotify to work, we won't be able to use this to simulate the hardware. If anyone wants to take a look and see if they can figure it out, feel free. Even if you don't, this project is a nice starting point for someone who wants to control Flexsim via an external application...as long as you don't need the OnUserNotify. I think if I understood a little better about what's going on on the Flexsim side I could maybe figure it out. I appreciate everyone's help. David White |
#34
|
||||
|
||||
David,
Unfortunately I don't know c# that well, especially in regards to COM, so I can't help you directly on your project. But I was able to get the user notify to work in VBA using the excel example originally posted with the COM object, here: ExcelwithUserNotify.zip. I just put in the entry trigger of the sink a call to usernotifycom when the sink's input hits 40. Then, in the excel file I added an event sink for the user notify, that just shows a message box. If you still can't figure out what's wrong, I'm also including the source code and Visual Studio Project for the COM dll's used. The "code trace" for calling usernotifycom is: 1. usernotifycom_commmand() is called, defined in FlexsimRPCServer>DLLMain.cpp. 2. A new thread is created that calls NewThreadOnUserNotify(), defined in FlexsimRPCServer>DLLMain.cpp. The main thread will then wait for that thread to finish. (I think I have to create a new thread because I want to allow the client to call functions from his side, and have the main thread available to perform those calls). 3. NewThreadOnUserNotify() calls RPC_OnUserNotify(), which is the rpc call that performs the inter-process communication 4. On the other process' side, the RPC_OnUserNotify() rpc event sink is fired, defined in FlexsimAXDLL>FlexsimAXApp.cpp, which fires the OnUserNotify() COM event sink. Hope this helps. Sorry it's a bit late. |
The Following 3 Users Say Thank You to Anthony Johnson For This Useful Post: | ||
Mike Goebel (05-02-2011) |
#35
|
|||
|
|||
Hi,
Thanks Anthony, for the FlexsimRPCDLL.zip upload! I think this COM-Object is exactly what I need to control Flexsim from the outside. I'm experimenting with this RPC-server for over a week now, but it still doesn’t work. Does somebody has a (small) example of a RPC-Client written in C(++) that will work with this RPC-Server? Please help, I’m getting a little discouraged. Cedric |
#36
|
|||
|
|||
Debug a user DLL
Hi,
I've not found nothing in the forum about debug a user DLL. I use this steps: 1 - compile in debug mode and be sure that the output folder contatin also the <mydllproject>.mdb (the debug database) 2 - If necessary I call an my exported dll function to force Flexsim to load my dll (something like 'libstartup') 3 - in VS2008 start a debug session using the 'attach to process' and select current Flexsim run process (usually flexsimrunner.exe) 4 - place my breakpoints in source code 5 - enjoy with debug! |
The Following 8 Users Say Thank You to Luciano For This Useful Post: | ||
Tom David (03-30-2010) |
#37
|
|||
|
|||
treenode names while debugging in DLL code
Hello,
Thanks Luciano, I like this very much! I now use it frequently to debug my DLL code. I have a question though, do you (or does anybody) know if it is possible to make the treenode names of the Flexsim objects visible in the Autos, Watch or Locals window in Visual Studio? What I mean is that an interger for example has a value of 1. A treenode (such as current) has a value of something like: 0x0a5d4a88. It would be great to be able to see the name of the current object somewhere in the Visual Studio window. Esther |
#38
|
|||
|
|||
I've just been adding a string variable where I've needed to know the name/path:
Code:
string currentname=nodetopath(current,1); I agree it would be nice if we could have some 'plug-in' that would do that automatically for treenodes. Maybe there's something in here that could help if someone has the time to figure it out. |
The Following User Says Thank You to Jason Lightfoot For This Useful Post: | ||
Luciano (05-12-2010) |
#39
|
|||
|
|||
Quote:
Would it work with Flexsim 6.0.2? It's crashing when trying to "StartApplication". Thanks, Andre. |