-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Merge pull request #1 from lynnporu/dev
Implement library
- Loading branch information
Showing
6 changed files
with
635 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,51 @@ | ||
<p align="center"> | ||
<img src="https://github.com/lynnporu/annotatec/raw/dev/logo.png"> | ||
</p> | ||
|
||
![PyPI](https://img.shields.io/pypi/v/annotatec) | ||
![GitHub repo size](https://img.shields.io/github/repo-size/lynnporu/annotatec) | ||
![GitHub](https://img.shields.io/github/license/lynnporu/annotatec) | ||
|
||
------------ | ||
|
||
**annotatec** helps you create Python packages with C embeddings. | ||
|
||
Imagine you're developing C library and already have more than 50 functions. Sometimes you change signatures of old functions or rename them. It'll be headache to write and support all [ctypes](https://docs.python.org/3/library/ctypes.html)-declarations for Python wrapper. **annotatec** will create all Python objects for you. All you need is to provide declarations, which can be placed directly into your C code. | ||
|
||
## Minimal livable example | ||
|
||
You have some library `lib.c` and it's header `lib.h`. These files were compiled into `lib.so` (or `lib.dll` in Windows). | ||
|
||
`lib.c` source: | ||
```c | ||
#include "lib.h" | ||
int sum(int a, short b, long long c) { return a + b + c; } | ||
``` | ||
`lib.h` source: | ||
```c | ||
/* @function sum | ||
* @return int | ||
* @argument int | ||
* @argument short | ||
* @argument longlong | ||
*/ | ||
int sum(int, short, long long); | ||
``` | ||
|
||
Here's a Python wrapper: | ||
```python | ||
import annotatec | ||
|
||
libc = annotatec.Loader( | ||
library="lib.so", headers=["lib.h"]) | ||
``` | ||
|
||
That's all! Now you can test it like so: | ||
```python | ||
>>> libc.sum(1, 2, 3) | ||
<<< 6 | ||
``` | ||
## Reference | ||
|
||
Read detailed reference in [wiki](https://github.com/lynnporu/annotatec/wiki)-pages. |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,2 @@ | ||
from .parser import * | ||
from .loader import * |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,42 @@ | ||
import ctypes | ||
import typing | ||
|
||
from . import parser | ||
|
||
|
||
class Loader: | ||
"""Base class for loading and parsing libraries. | ||
""" | ||
|
||
def __init__( | ||
self, | ||
library: typing.Union[str, ctypes.CDLL], | ||
headers: typing.List[typing.Union[str, typing.TextIO]], | ||
precompile: bool = True | ||
): | ||
"""Loads library and parse headers. | ||
Arguments: | ||
library: str or ctypes.CDLL - address of the shared objects (DLL) | ||
or opened library. | ||
headers: list of strings or list of files - files with declarations | ||
to parse. | ||
precompile: bool - if set to True, than all objects will be | ||
compiled immediately. This option allows to lazy compile | ||
only objects that are needed. | ||
""" | ||
|
||
self.libc = ( | ||
ctypes.cdll.LoadLibrary(library) | ||
if isinstance(library, str) | ||
else library) | ||
self.parser = parser.FileParser(lib=self.libc) | ||
|
||
if precompile: | ||
self.parser.parse_files(headers) | ||
else: | ||
self.parser.scrap_files(headers) | ||
|
||
def __getattr__(self, key): | ||
return self.parser.declarations.compile(key) |
Oops, something went wrong.