ID:259301
 
You know, this thread has me thinking of a great feature for BYOND 3.x after the next version is released and stabilizes to the point that Dantom can get back to feature creep:

call_external

Format:
call_external(image,entry,vars,value)
Returns:
The value returned by the external function.
Args:
image: name of the file, which must be a sharable object library (UNIX) or DLL (Windows) which contains the routine to be called.
entry: entry point of the procedure or function.
vars: list containing the variables to be passed to the called routine.
value: list of 1's and 0's corresponding to the variables passed to the routine. 1 means pass by value, 0 (default) means pass by reference.

The call_external proc calls a function in an external sharable object and returns a value. Routines called in this way must adhere to the C (argc, argv) calling convention.

Example:

Assume you wish to call a routine to add some numbers together. The C routine might look something like this:
#include
float sum_array(int argc, void *argv[])
{
  float s = 0.0;
  int i;
  for(i = 0; i < argc; i++)
    s += (float)argv[i];
  return(s);
}
The following statements could be used to compile the example and produce a sharable object library on the Linux operating system:
gcc -fPIC -c example.c
ld -shared -o example.so example.o
The compiled routine can then be called from BYOND using the following code:
var/nums[] = list(1.43, 0.44, 5.478, 22)
var/vflags[] = list(1, 1, 1, 1)
var/sum = call_external("example.so", "_sum_array", nums, vflags)

This could be an incredibly powerful feature - if BYOND doesn't directly support what a game developer wants to do, no problem! Just call an external routine to do it. The inverse, a library of C functions to call a BYOND proc from within a C/C++ program would be just as useful.
On 4/4/01 11:54 am Air Mapster wrote:
<h2>call_external</h2>
Format:
call_external(image,entry,vars,value)
Returns:
The value returned by the external function.



Now that's putting pressure on Dantom -- pre-providing the documentation!

Along these lines, it could be a big step to solving one item that keeps some smart programmers I know from considering BYOND: The inability to imbed something like a Perl parser and thereby get all sorts of extra Perl stuff for free. (Like Perl libraries to access databases and stuff like that.)
In response to Deadron
On 4/4/01 12:00 pm Deadron wrote:
Along these lines, it could be a big step to solving one item that keeps some smart programmers I know from considering BYOND: The inability to imbed something like a Perl parser and thereby get all sorts of extra Perl stuff for free. (Like Perl libraries to access databases and stuff like that.)

Oh, I would kill for access to a perl interpreter within BYOND! Just last night I was thinking of when an Una player in automatic mode disconnects and is replaced by a computer, the name becomes an unwieldy "PlayerName [Auto] [Computer]." Sure, it'll be easy enough to replace [Auto] with [Computer] using BYOND's text processing, but I haven't looked at it yet because that would mean reading a little documentation. ;-) I'd love to be able to do:
name = run_perl("$_ = \"[name]\"; s/\[Auto\]/\[Computer\]/; $_;")

I know I've thought of other situations but that's the first that comes to mind.

Well, now that I know there is somebody who wants this, maybe I'll bump it up higher on my list! (And I don't even have to write the documentation. How convenient!)

A game that links to external libraries is obviously not going to be as portable. That's one reason I have not made this a priority in the past. I want to make sure we have the most important functionality built directly into BYOND so that most games can remain portable.

Yes, perl can be installed on any platform, but I don't want to be responsible for doing that when a user downloads a game from the hub. Too much headache.

Also, security is obviously out of the question in windows when the code makes calls to external DLLs. Currently, when you download and run something from the hub, you can be confident that it cannot do any damage to your computer, because it is running in "safe" or "ultrasafe" mode. That's a pretty nice feature.

--Dan
In response to Dan
On 4/5/01 8:44 am Dan wrote:
A game that links to external libraries is obviously not going to be as portable. That's one reason I have not made this a priority in the past. I want to make sure we have the most important functionality built directly into BYOND so that most games can remain portable.

I would assume that games using this would be server-based, so that installation/portability isn't an issue.
Just as a thought - I figure I'd bump this and see what happens ;)
In response to Alathon
It's the OOBAR BUMP!!! You've got guts. =p

I wouldn't mind a Perl/Python/PHP/Whachamacalit methods. Just have to watch out for those security vulnerabilities. And in the case of calling external code, translating DM values into basic data types.
In response to Alathon
Alathon wrote:
Just as a thought - I figure I'd bump this and see what happens ;)

I could probably work out how to implement this, but there is still the question of whether that would be a good idea for security reasons. However, an idea has occurred to me: If accessing a DLL at all had to go through a security check just like shell() does now, it could be made to work. Of course, needless to say portability does go out the window.

Lummox JR
In response to Lummox JR
Lummox JR wrote:
If accessing a DLL at all had to go through a security check just like shell() does now, it could be made to work.

But then hosts might just blindly click "yes" to everything to get the game to work, and then find their computer infected with a virus. :(
In response to Jon88
Jon88 wrote:
But then hosts might just blindly click "yes" to everything to get the game to work, and then find their computer infected with a virus. :(

Honestly, I think that excuse is slightly out of the window the moment you choose to install Windows, browse the web and such.

Lummox JR wrote:
If accessing a DLL at all had to go through a security check just like shell() does now, it could be made to work.

That sounds like a fine compromise to me - There are quite a lot of benefits to this, I think the benefits definately outweigh the possible security risks (Which really are overprotective, for todays standards - Not that I disagree with being careful).
In response to Lummox JR
Lummox JR wrote:
Of course, needless to say portability does go out the window.

Implement Linux support as well? So you can load those .so files?
In response to Android Data
Android Data wrote:
Lummox JR wrote:
Of course, needless to say portability does go out the window.

Implement Linux support as well? So you can load those .so files?

It would have to be done by altering the Linux client. Which is to say, not by me.

Lummox JR
In response to Lummox JR
Isn't the server-side code pretty much the same across both Windows and Linux?

I'm sure there's a cross-platform C code snippet for linking to shared libraries out there somewhere. All you need to do is wrap both Windows's LoadLibrary/GetProcAddress functions and Linux's dlopen/dlsym functions within the same interface.

Of course you'd need some mechanism for specifying alternate filenames depending on operating system. And even within an operating system; under Linux, by convention the library name changes for each release (though symbolic links are maintained so that you can always link to "the latest version" without knowing its version number).
In response to Crispy
Crispy wrote:

Of course you'd need some mechanism for specifying alternate filenames depending on operating system

Easy, just have the DM code ask for a module name without the extension. Then DreamDaemon (or whatever) can simply add ".dll" for windows, ".so" for Linux and ".dylib" for OS X and the BSDs.


And even within an operating system; under Linux, by convention the library name changes for each release.

This is not really a problem as the DLLs would have to be designed for BYOND (who writes functions that take variable length arrays of floats? :P) so you wouldn't be using system libraries anyway. You can use whatever naming scheme you like, they don't even have to be called .so either - it's just a name.
In response to Alathon
Alathon wrote:
That sounds like a fine compromise to me - There are quite a lot of benefits to this, I think the benefits definately outweigh the possible security risks

What are some of the possible uses you have in mind for it?

It would be ok for games with central dedicated servers, but enabling games to bundle DLLs with them is a really bad idea. It'd just get messy both in terms of security and usability (binary compatibility across Linux versions can be poor and there's even problems in Windows). I'd advocate doing something like making it only work in a standalone dream daemon.
In response to BobOfDoom
BobOfDoom wrote:
It would be ok for games with central dedicated servers

Thats exactly what I have in mind ;)
In response to BobOfDoom
BobOfDoom wrote:
This is not really a problem as the DLLs would have to be designed for BYOND (who writes functions that take variable length arrays of floats? :P) so you wouldn't be using system libraries anyway.

True, didn't think about that.
In response to Air Mapster
Hmmm, that gives me a weird idea.
In response to Crispy
Crispy wrote:
Isn't the server-side code pretty much the same across both Windows and Linux?

I was thinking in terms of the server interface (i.e. Dream Daemon), not the backend. It's this that actually pops up a window to ask you a permission question, but it's told what to ask by the backend code.

I'm sure there's a cross-platform C code snippet for linking to shared libraries out there somewhere. All you need to do is wrap both Windows's LoadLibrary/GetProcAddress functions and Linux's dlopen/dlsym functions within the same interface.

I'm not sure if the Linux version is set up to handle any user queries like "Is it safe to use that file?" If it is, excellent. But I do know that Dream Daemon for Windows wasn't able to do this until the new version, so the Linux interface may be lacking. Of course on servers this complicates the problem, unless the host thinks to run the program in trusted mode.

Of course you'd need some mechanism for specifying alternate filenames depending on operating system. And even within an operating system; under Linux, by convention the library name changes for each release (though symbolic links are maintained so that you can always link to "the latest version" without knowing its version number).

The soft code should already be able to grab a flag that says which OS is in use, so let the game's author worry about it I say. The main issue is, very few people are capable of actually doing such cross-platform development, so most games that used this feature would not support two different OSes for it.

Lummox JR
In response to Lummox JR
Lummox JR wrote:
The main issue is, very few people are capable of actually doing such cross-platform development, so most games that used this feature would not support two different OSes for it.

That is a bit of a shame, yes, but IMO it's worth it. Especially since this feature would probably mostly be used on privately hosted servers, rather than for downloadable games.