Browse Source

Initial commit. Non-functional

master
Dirkson 5 years ago
commit
7fe21f0b5d
  1. 40
      .gitignore
  2. 21
      LICENSE
  3. 92
      README.md
  4. 55
      include/dynload.h
  5. 39
      src/dynload.c
  6. 3
      src/generator.c

40
.gitignore

@ -0,0 +1,40 @@
#Vim files
*.un~
*.swp
# Object files
obj/*
*.o
*.ko
*.obj
*.elf
# Precompiled Headers
*.gch
*.pch
# Libraries
lib/*
*.lib
*.a
*.la
*.lo
# Shared objects (inc. Windows DLLs)
*.dll
*.so
*.so.*
*.dylib
# Executables
*.exe
*.out
*.app
*.i*86
*.x86_64
*.hex
bin/*
# Debug files
*.dSYM/
*.su

21
LICENSE

@ -0,0 +1,21 @@
MIT License
Copyright (c) 2017 Dirkson
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.

92
README.md

@ -0,0 +1,92 @@
# libdynload
libdynload is a cross-platform system for dynamically loading arbitrary libraries.
Hand it a .h and a list of functions, and it creates a library that dynamically loads your library. Hopefully.
libdynload.a and its generated libraries should work on POSIX operating systems (linux, bsd, osx, etc.) and windows.
# HowTo
make dynload
make dynloadgen
./dynloadgen name /path/to/some.h /path/to/functionslist.txt
Only those functions provided by the functionlist will be provided.
# Example
First our two input files:
bob.h
```
extern int Foo();
extern char* Bar(char *);
extern int Baz();
```
bobfuntions.txt
```
Foo
Bar
```
Now we run our dynamic loader generator on the input files:
```
make dynloadgen && ./bin/dynloadgen bob bob.h bobfunctions.txt
```
It makes a directory named "dynload_bob"
```
$ ls dynload_bob
dynload_bob/dynload_bob.h
dynload_bob/dynload_bob.c
```
dynload_bob/dynload_bob.h:
```
typedef int (*dynload_bob_Foo)();
typedef char* (*dynload_bob_Bar)(char *);
#define Foo ((dynload_bob_Foo)dynload_bob.function_pointers[0])
#define Bar ((dynload_bob_Bar)dynload_bob.function_pointers[1])
dynload_library dynload_bob;
```
dynload_bob/dynload_bob.c:
```
#include "dynload_bob.h"
#define DYNLOAD_BOB_FUNCTION_NUM 2
char* dynload_bob_function_names[DYNLOAD_BOB_FUNCTION_NUM] = { "Foo", "Bar" };
void* dynload_bob_function_pointers[DYNLOAD_BOB_FUNCTION_NUM];
dynload_bob = { NULL, &dynload_bob_function_names, &dynload_bob_function_pointers, DYNLOAD_BOB_FUNCTION_NUM };
```
Now to use these files, we insert the c into our build system, and insert the following code into our project. example.c:
```
#include <bob.h>
#include <dynload.h>
#include "dynload_bob.h"
int main()
{
dynload_load(&dynload_bob);
Foo();
return 0;
}
```
$ FAQ
Q: Why are function pointers stored in void\* arrays, rather than directly in the structs?
A: Doing it this way allows for substantially less generated code, and reuse of the dynload_load/unload code. It also almost forces you to use the provided macros, keeping your own code more readable and maintainable.

55
include/dynload.h

@ -0,0 +1,55 @@
typedef struct {
void* handle;
char* function_names;
void* function_pointers;
unsigned int function_num;
} dynload_library;
//Example:
// Input files:
//
// bob.h
// extern int Foo();
// extern char* Bar(char *);
// extern int Baz();
// bobfunctions.txt
// Foo
// Bar
//
// Now we need to generate our library:
// dynloadgenerate bob.h bob bobfunctions.txt
//
// dynload_bob.h
// typedef int (*dynload_bob_Foo)();
// typedef char* (*dynload_bob_Bar)(char *);
// #define Foo ((dynload_bob_Foo)dynload_bob.function_pointers[0])
// #define Bar ((dynload_bob_Bar)dynload_bob.function_pointers[1])
// dynload_library dynload_bob;
// dynload_bob.c
// #define DYNLOAD_BOB_FUNCTION_NUM 2
// char* dynload_bob_function_names[DYNLOAD_BOB_FUNCTION_NUM] = { "Foo", "Bar" };
// void* dynload_bob_function_pointers[DYNLOAD_BOB_FUNCTION_NUM];
// dynload_bob = { NULL, &dynload_bob_function_names, &dynload_bob_function_pointers, DYNLOAD_BOB_FUNCTION_NUM };
//
// How to USE this:
//
// example.c:
// #include <bob.h>
// #include <dynload.h>
// #include "dynload_bob.h"
// dynload_load(&dynload_bob);
// Foo();
//
//All external functions return one of the following return codes.
//Positive return codes are success, negative are failure
typedef enum {
DYNLOAD_SUCCESS
DYNLOAD_ERR_UNKNOWN
DYNLOAD_ERR_NOFILE
} DYNLOAD_RETURN;
extern DYNLOAD_RETURN dynload_load(*dynload_library);
extern DYNLOAD_RETURN dynload_unload(*dynload_library);

39
src/dynload.c

@ -0,0 +1,39 @@
#include "loadglfw.h"
#include <lob.h>
//#include <dlfcn.h> - Linux only
typedef GLFWwindow* (*ptr_glfwCreateWindow)(int, int, const char *, GLFWmonitor *, GLFWwindow *);
ptr_glfwCreateWindow loadglfw_glfwCreateWindow;
typedef int (*ptr_glfwInit)();
ptr_glfwInit loadglfw_glfwInit;
#define test_run() ((tTestFuncSignature)hehe_stack_pop(tests))();
// Dynamically load glfw on linux. If we fail, we can fall black to the plain gui
// If we end up needing to do this on multiple platforms in the future, we should switch to:
// https://github.com/lethosor/libdylib
// This may be an issue on bsds as well
dynload()
{
//Load .so
void *glfwLib = dlopen( "libglfw.so", RTLD_LAZY);
if (glfwLib == NULL)
return lob(LOB_STDOUT, LOB_ERROR, "Can't locate libglfw.so . Please install glfw3. On debian/ubuntu the command to install it is: sudo apt-get install libglfw3");
//Check for other errors
char *dlErrorString = dlerror();
if (dlErrorString != NULL)
return lob(LOB_STDOUT, LOB_ERROR, "There's been an issue loading glfw: %s ", dlErrorString);
//Load functions
// if ((glfwInit = dlsym(glfwLib, "glfwInit")) == NULL)
// return lob(LOB_STDOUT, LOB_ERROR, "Failed to load glfwInit");
if ((simsecl_glfwInit = dlsym(glfwLib, "glfwInit")) == NULL)
return lob(LOB_STDOUT, LOB_ERROR, "Failed to load glfwInit");
if ((simsecl_glfwCreateWindow = dlsym(glfwLib, "glfwCreateWindow")) == NULL)
return lob(LOB_STDOUT, LOB_ERROR, "Failed to load glfwCreateWindow");
return 1;
}

3
src/generator.c

@ -0,0 +1,3 @@
#include <>
Loading…
Cancel
Save