Variables declared like this
bMyVar AT %MB100: BOOL;
can be accessed from another PLC by using the ADS read or write FB. Other programs, like the HMI Movicon, use the .tpy file in order to get a list of the available variables. Unfortunately variables declared with a memory location like the above are not present in the TPY file and cannot be read from the HMI software. Why does this happen if Twincat itself is able to read these variables using ADS? (HMI uses ADS too..)
Related
I have programed Lua script to a game with function os.clock() and os.time(). Its worked correctly, but after upgrade of this game I have observed fail message : attempt to call global 'os' (a nil value)... ? I thought that os.clock() and os.time() are native function of Lua.
From the Lua reference manual:
Except for the basic and the package libraries, each library provides
all its functions as fields of a global table or as methods of its
objects.
To have access to these libraries, the C host program should call the
luaL_openlibs function, which opens all standard libraries.
Alternatively, the host program can open them individually by using ... luaopen_os (for the operating system library)...
As you see adding the standard libraries in a host program is optional. Many applications restrict access to standard libraries. Especially os and io.
As the os librarie has not been added to the scripting environment of your game the global table os is nil.
So obviously the developers of your game decided that their users should survive without the os functions. Sometimes they just don't want you to do things, sometimes it just doesn't make sense. It is the simplest way to prevent you from interacting with the operatinig system from inside a game.
Usually they also prevent you from loading external code by removing the necessary functions.
I have an application which has sound. I have a global property to mute the sound. The problem is, there's so many different things which can make sound, I would hate to iterate through different class types and mute/unmute their sound. Instead, I'm looking for a way to mute the sound on a global application level. I don't mean muting the entire system volume either.
One scenario: In Windows 7, you can open the Volume Mixer and adjust the volume of individual applications. While I don't intend to change this actual particular value (as I know it's Windows 7 specific), I would like to change the volume of everything in my application all at once. I would also need the ability to completely mute the sound of everything in my application. I need this ability to be compatible with Windows XP and above. I am assuming it will involve Windows API calls, but I have no idea what calls to make.
XP does not support per-application volume control. That capability was added in Vista. So what you are attempting to do cannot be done in XP by fair means.
There is software called IndieVolume that retro fits per-app volume control to XP. I can only imagine it does so by means of low-level hacking, DLL injection and so on. I doubt that's really an option for you.
What you're asking for isn't possible on XP; the OS simply does not support per-application volume levels.
You can accomplish what you want by creating a settings class that keeps things like SoundActive: Boolean or PlaySounds: Boolean or something similar. Place it in it's own unit, and have an initialization section that creates an instance of it and a finalization section that frees it (making it effectively a collection of global values).
Each unit that needs access to these settings simply uses the unit containing them, and adjusts behavior accordingly. So each of your child classes or forms or whatever would just need a check added:
if CurrentSettings.PlaySounds then
// Code that makes sounds, plays music, whatever.
The settings class can also contain methods that keep track of the current volume level (on XP, the system-wide level), and methods to increase or decrease volume using the MMSystem volume functions (there are tons of examples here and through Google of doing so). Your app can then use the OnActivate and OnDeactivate events to set the volume level when your app gains focus, and restore it to the proper volume when your app loses focus.
In Vista and higher, you can use the IAudioEndPointVolume interface I mentioned earlier and either the GetMasterVolumeLevel or SetMasterVolumeLevel methods to control system wide volume (I have an example of doing this, along with the appropriate MMDevAPI interface definitions) or device level volume (using IMMDevioce.Activate to select the proper device first and then the above IAudioEndPointVolume methods on the device interface received from IMMDevice.Activate in the ppInterface parameter).
For individual applications, you use the ISimpleAudioVolume interface, which has four methods: GetMasterVolume and SetMasterVolume, which control the volume level for your application's audio session, and GetMute and SetMute to allow you to retrieve the current mute flag value or set it respectively. (Larry Osterman of MS, who was one of the developers who worked on the new audio support in Vista and Win7, has a great starting point article on his blog about the types of audio in the new API and when to use each of them.)
It's conceptually possible to determine at runtime which operating system you're using, and to programmatically switch between using the MMSystem functionality on XP and earlier, and the MMDevAPI functionality on Vista and higher. Expecting someone here to provide the code for doing so is a little unreasonable, however. The links I've provided should get you started on the right track, and when you run into snags along the way specific help in working through those snags would be great questions.
Closed. This question is opinion-based. It is not currently accepting answers.
Want to improve this question? Update the question so it can be answered with facts and citations by editing this post.
Closed 7 years ago.
Improve this question
I have been reading about environment variables in Linux. I can understand how to set / read them.
What I want to ask is conceptually why were environment variables added to Linux ? Is there a system requirement that cannot be fulfilled without them ?
To my mind, it seems like an additional configuration layer was needed for some reason, something that was decoupled from the actual process functionality. I want to know the opinion of more experienced developers.
environment variables [herein: env] fulfill a need that can't [conveniently] be handled in other ways.
So, we ask the question: How do programs get configuration data that may change on each invocation?
We could pass everything as program arguments: pgmA PATH=... DISPLAY=... but the program would have to parse that. And, when pgmA invokes pgmB, it would have to pass this data along as arguments. In other words, every program would have to be aware of every variable, even if it had no use for the variable itself.
We could put everything in a config file, but we'd need a different one for each invocation. Where to put these files, how to guarantee they have unique names, how/when to delete them when they're no longer needed [even in the face of an aborted program], becomes intractable.
With env variables, they reside in the program in a special memory section that the kernel creates when the program is execed, and the std execvp et. al. (with some kernel help) will cheerfully pass along this environment without most programs having to do anything.
However, pgmA is at liberty, after a fork, and in the child before execvp to change something for pgmB (e.g. adds an extra directory to PATH). In other words, env is hierarchical between parent and child (e.g. changing child does not change parent--a good thing)
The env also allows things to be passed around that lower order programs need. Consider that pgmA fork/execs pgmB which in turn fork/execs pgmC. pgmA/pgmB are just ordinary programs [and don't use any env variables themselves]. But pgmC is xterm which needs to know what X11 display to output on. It gets that from the DISPLAY env var.
Consider that we ran the above from the main GUI console from within a window terminal program. DISPLAY would [probably] be :0. The xterm shows up on the local screen. Now consider that we do the same exact thing from an ssh login. Here DISPLAY will be w.x.y.z:0 and the xterm will execute on the local machine, but will display itself on the remote system's screen.
Another major use of the environment is to provide configuration for things that don't have [legitimate] access to argv or config files. Namely, shared libraries [.sos]. Here are two examples:
When an ELF program is execed by the kernel, it maps the executable file into memory. It then looks in a special section for the "ELF loader", which, under Linux is (e.g.) /lib64/ld-linux-x86-64.so.2. The kernel maps the loader into the application memory and turns control of the program over to the loader. The loader, in turn, resolves references to, and loads, the shared libraries the program needs, and then transfers control to the program's start function.
The ldd program will print out the shared libraries that a given program uses. But, it doesn't actually do that itself. It sets an env variable, then execs the target program. The ELF loader sees this variable, and instead of executing the program, it merely loads it, printing the names of the shared libraries. The ELF loader has many env vars that can affect its operation (e.g. see man ld.so).
Another library that uses the environment is glibc. When glibc encounters a fatal error, such as double freeing a pointer, or heap corruption, it will print an error message. Normally, glibc will output this to /dev/tty. Sometimes, that's not desirable and we'd rather the error message go to stderr [where we've opened an error log file]. To get glibc to honor our wishes, we set the env var LIBC_FATAL_STDERR_ to 1 before we invoke the program.
This config stuff could be handled by a WinX registry-like interface and the data could reside in per-process kernel memory. But, that's cumbersome for the kernel and the program. The kernel doesn't want to carry this variable sized information in [precious] kernel address space. An application doesn't want the overhead of using syscalls to get at it.
Most C programmers write their main function as int main(int argc,char **argv) but with what gets actually passed it could [more properly] be written as int main(int argc,char **argv,char **envp). The envp actually points to a definition:
char *environ[] = {
"DISPLAY=:0",
"PATH=/usr/bin:/bin",
...
NULL
};
The libc functions getenv, setenv, putenv operate on the global. But, when passing the pointer to execvpe you can specify a different env array altogether, filled with whatever you want. So, you can manipulate the array [and, hence, the environment] directly.
Historical footnote: environment variables aren't specific to Linux. They weren't added--they have always been there [in Linux]. And, the environment has been part of just about any unix-like system, unchanged(!), since the earliest incarnations, just like argc/argv. This goes back to [at least] Bell Labs' Unix V7 [and probably earlier].
Variables are used for writing scripts and program management. For example, you can write a script greeting and indicate in it the variable $ USER, and it will display the name of the current user. Programs can access variables, and variables can be used in their work. For example, the programs running in the GUI on Linux, you can specify the X server, with which they will display their data.
Environment variables is really helpful for running programs on Linux. We usually need to read some system configurations in our program and environment variable is a good place to allow us to access these configurations.
Right now I am doing a lot of.
local env = {
print = print,
}
setfenv(func, env)
and then using metamethods to lock propertys on Instances, but it is really inefficient and has lots of bypasses. I googled it and everything I find is the same as this: unworking.
In Lua 5.1, sandboxing is pretty simple. If you have a Lua script in a file somewhere, and you want to prevent it from accessing any functions or anything other than the parameters you provide, you do this:
local script = --Load the script via whatever means. DO NOT RUN IT YET!
setfenv(script, {})
script is now sandboxed. It cannot access anything other than the values you directly provide. Functions it creates cannot access anything outside of this sandbox environment. Your original global environment is completely cut off from them, except for what you permit it to access.
Obviously you can put whatever you like in that table; that table will contain whatever globally accessible stuff you like. You should probably give Lua scripts access to basic Lua standard library functions; most of those are pure functions that can't do anything unpleasant.
Here's a list of Lua standard library stuff that you must not give the user access to, if you want to maintain the integrity your sandbox:
getfenv. There are valid reasons for a user to be able to setfenv, so that it can create mini-sandboxes of its own within your sandbox. But you cannot allow access to the environment of any functions you put in the sandbox if you want to maintain the integrity of the sandbox.
getmetatable: Same reasoning as above; setting metatables is OK. Though malicious code can break an object if they change its metatable, but malicious code can break your entire system just by doing an infinite loop.
The entire debug library. All manner of chicanery is possible through the debug library.
You also apparently need to solve this problem that Lua 5.1 has with loading bytecode from within a Lua script. That can be used to break the sandbox. Unfortunately, Lua 5.1 doesn't really have good tools for that. In Lua 5.2+, you can encapsulate load and loadfile, such that you internally pass "t" as the mode parameter no matter what the user provides. But with Lua 5.1, you need some way to encapsulate load et.al. such that you can tell when the data is text and when it's not. You could probably find the code that Lua uses to distinguish bytecode from text by reading the Lua source.
Or you can just disallow load and its friends altogether.
If you want to prevent the user from doing ugly things to the system, then disallow the os and io libraries.
I just played around a bit with Lua and tried the Koneki eclipse plugin, which is quite nice. Problem is that when I make changes in a function I'm debugging at the moment the changes do not become effective when saving the changes. So I'm forced to restart the application. Would be so nice if I could make changes in the debugger and they would become effective on the fly as for example with Smalltalk or to some extend as in hot code replacement in Java. Anybody has a clue whether this is possible?
It is possible to some degree with some limitations. I've been developing an IDE/debugger that provides this functionality. It gives you access to a remote console to execute commands in the context/environment of your running application. The IDE also supports live coding, which reloads modified code as you make changes to it; see demos here.
The main limitation is that you can't modify a currently running function (at least without changes to Lua VM). This means that the effect of your changes to the currently running function will only be seen after you exit and re-enter that function. It works well for environments that call the same function repeatedly (for example a game engine calling draw), but may not work in your case.
Another challenge is dealing with upvalues (values that are created outside of your function and are referenced inside it). There are methods to "read" current upvalues and re-create them when the (new) function is created, but it requires some code analysis to find what functions will be recreated to query them for upvalues, to get the current values, and then to create a new environment with those upvalue and assign proper values to them. My current implementation doesn't do this, which means you need to use global variables as a workaround.
There was also relevant discussion just the other day on the Lua mailing list.