Who needs a scripting language? When compiled C will do.

Whether you're a newbie or an experienced programmer, any questions, help, or just talk of any language will be welcomed here.

Moderator: Coders of Rage

Post Reply
User avatar
avansc
Respected Programmer
Respected Programmer
Posts: 1708
Joined: Sun Nov 02, 2008 6:29 pm

Who needs a scripting language? When compiled C will do.

Post by avansc »

Okay, well maybe thats a little miss leading, and yes, perhaps there are things this following method can't do that you can in some scripting language.
This method however does allow you to dynamically use compiled C code, WITHOUT changing the codebase.

What we are going to be using is called dynamic linking, dlfcn.h is the header that will give us all the goodies to do this.

NOTE : This will require you to do some planning because you have to have a alias to get to the code in in the library you will dynamically linked.

lets look at this code.

dynamic.h

Code: Select all

#ifndef _dynamic_h
#define _dynamic_h

extern "C" int calc(int a);

#endif
dynamic.cpp

Code: Select all

#include <stdio.h>

#include "dynamic.h"

int calc(int a) {
	return a*a;
}
Okay, so thats pretty straight forward, we compile this code into a dynamic library, that would be dll/so/dylib for window/linux/osx, respectively.
i called it dynamic and my particular extension was dylib.(OSX)

Now for the main code.

main.cpp

Code: Select all

#include <stdio.h>
#include <stdlib.h>
#include <dlfcn.h>

int main(void)
{
	void *handle;
	int (*calc)(int);
	
	handle = dlopen("dynamic.dylib", RTLD_NOW);
	if(handle == NULL) {
		printf("%s\n", dlerror());
		exit(1);
	}
	
	calc = (int(*)(int)) dlsym(handle, "calc");
	
	if(dlerror() != NULL)
	{
		printf("%s\n", dlerror());
		exit(-1);
	}
	
	for(int a = 1;a <= 5;a++)
		printf("%d squared = %d\n", a, calc(a));
	
	dlclose(handle);
	
	return 0;
}
the most important line is, calc = (int(*)(int)) dlsym(handle, "calc");
here it looks for a function called calc in the library that we loaded, (well the extern C bit, but yanno).

and well the rest is pretty straight forward.

on a side note i have been trying to do it where you have a single base class with a few smart virtual functions, then the libraries would have inherited that, so that you only use say cNPC in the main program, but you can extend the code base dynamically by making class cDragon : public cNPC or something like that. but im having a little issue where it will load fine but its crashing once i call functions on the NPC class that are virtual. anyways.

if you spend some time and make a few functions that will stay consistent you can really use this to your advantage.
you can change entire render systems and so on, make expansions like this, levels, weapons, the possibilities really are endless. and the best part of all is that its compiler, so its fast, and you dont have to change your codebase.
Some person, "I have a black belt in karate"
Dad, "Yea well I have a fan belt in street fighting"
User avatar
Ginto8
ES Beta Backer
ES Beta Backer
Posts: 1064
Joined: Tue Jan 06, 2009 4:12 pm
Programming Language of Choice: C/C++, Java

Re: Who needs a scripting language? When compiled C will do.

Post by Ginto8 »

So basically this has you compile all the "script" functions into a shared/dynamic library, and then dynamically use those functions from the executable? That sounds cool :)
Quit procrastinating and make something awesome.
Ducky wrote:Give a man some wood, he'll be warm for the night. Put him on fire and he'll be warm for the rest of his life.
User avatar
GroundUpEngine
Chaos Rift Devotee
Chaos Rift Devotee
Posts: 835
Joined: Sun Nov 08, 2009 2:01 pm
Current Project: mixture
Favorite Gaming Platforms: PC
Programming Language of Choice: C++
Location: UK

Re: Who needs a scripting language? When compiled C will do.

Post by GroundUpEngine »

Custom dll's, I like it! :)
User avatar
avansc
Respected Programmer
Respected Programmer
Posts: 1708
Joined: Sun Nov 02, 2008 6:29 pm

Re: Who needs a scripting language? When compiled C will do.

Post by avansc »

Okay, so i finally got inherited classes to work, this is really where this technique will pull a bukake on a scripted version.

In this example you have a base class, cNPC. that gets compiled into your main app. Now, we want to make a dragon enemy, but its not really nice having to have to recompile the base just to add a new character or enemy. and its really impractical if you have a shipped version of the game.

so here we compile a new dynamic library that inherits from the cNPC class, and over rides functions that characters need to do, in this case i just have attack, since this is just for academic illustration.

then when you use the cNPC in the codebase it will act like the COMPILED code of the dragon.

lets take a look at the code.

cNPC.h // i dont have a cNPC.cpp since its so minimal

Code: Select all

#ifndef _cNPC_h
#define _cNPC_h

class cNPC
{
public:
	virtual void attack() const = 0;
};

typedef cNPC *create_t();
typedef void destroy_t(cNPC*);

#endif
cDragon.h

Code: Select all

#ifndef _cDragon_h
#define _cDragon_h

#include "cNPC.h"

class cDragon : public cNPC
{
public:
	virtual void attack() const;
};

extern "C" cNPC* create();
extern "C" void destroy(cNPC *t);

#endif
cDragon.cpp

Code: Select all

#include <stdio.h>

#include "cDragon.h"

void cDragon::attack() const
{
	printf("Dragon attack!\n");
}

cNPC* create()
{
	return new cDragon;
}

void destroy(cNPC *t)
{
	delete t;
}
main.cpp

Code: Select all

#include <stdio.h>
#include <stdlib.h>
#include <dlfcn.h>

#include "cNPC.h"

int main(void)
{	
	void *handle = dlopen("cDragon.dylib", RTLD_NOW);
	
	if(handle == NULL) {
		printf("%s\n", dlerror());
		exit(1);
	}
	
	create_t* create_npc = (create_t*)dlsym(handle, "create");
	destroy_t* destroy_npc = (destroy_t*)dlsym(handle, "destroy");
	
// should check for errors here, but fux that for now.

	cNPC *dragon = create_npc();
	dragon->attack();
	
	
	return 0;
}
Some person, "I have a black belt in karate"
Dad, "Yea well I have a fan belt in street fighting"
User avatar
TheOtherGyro
Chaos Rift Newbie
Chaos Rift Newbie
Posts: 4
Joined: Mon Apr 19, 2010 1:38 pm
Current Project: Some surrealist machine-building platformer thing.
Favorite Gaming Platforms: PC Master Race
Programming Language of Choice: C++ master race
Contact:

Re: Who needs a scripting language? When compiled C will do.

Post by TheOtherGyro »

Problem with this is, most modders and mappers don't know C++. Also, that sounds like it would be a bitch to port to another platform.

Other than that, it's pretty cool. It sounds to me like that would be blazing fast compared to using a scripting language. Have you done any benchmarking?
User avatar
Falco Girgis
Elysian Shadows Team
Elysian Shadows Team
Posts: 10294
Joined: Thu May 20, 2004 2:04 pm
Current Project: Elysian Shadows
Favorite Gaming Platforms: Dreamcast, SNES, NES
Programming Language of Choice: C/++
Location: Studio Vorbis, AL
Contact:

Re: Who needs a scripting language? When compiled C will do.

Post by Falco Girgis »

TheOtherGyro wrote:Problem with this is, most modders and mappers don't know C++. Also, that sounds like it would be a bitch to port to another platform.

Other than that, it's pretty cool. It sounds to me like that would be blazing fast compared to using a scripting language. Have you done any benchmarking?
It would be blazingly fast, but the entire point of a scripting language is that you don't have to compile the assets.

And yeah, that's not very platform independent.
Post Reply