@yuuang/ffi-rs-linux-arm64-musl
Advanced tools
Comparing version 1.0.22 to 1.0.23
{ | ||
"name": "@yuuang/ffi-rs-linux-arm64-musl", | ||
"version": "1.0.22", | ||
"version": "1.0.23", | ||
"os": [ | ||
@@ -5,0 +5,0 @@ "linux" |
276
README.md
@@ -54,6 +54,8 @@ # ffi-rs | ||
- object(Nested object is not supported at this time) | ||
- function(developing) | ||
- function | ||
## Support Platform | ||
Note: You need to make sure that the compilation environment of the dynamic library is the same as the installation and runtime environment of the `ffi-rs` call. | ||
- darwin-x64 | ||
@@ -72,2 +74,6 @@ - darwin-arm64 | ||
### write c/c++ code | ||
Note: The return value type of a function must be of type c | ||
```cpp | ||
@@ -91,54 +97,9 @@ #include <cstdio> | ||
extern "C" void noRet() { printf("%s", "hello world"); } | ||
extern "C" int *createArrayi32(const int *arr, int size) { | ||
int *vec = (int *)malloc((size) * sizeof(int)); | ||
for (int i = 0; i < size; i++) { | ||
vec[i] = arr[i]; | ||
} | ||
return vec; | ||
} | ||
extern "C" double *createArrayDouble(const double *arr, int size) { | ||
double *vec = (double *)malloc((size) * sizeof(double)); | ||
for (int i = 0; i < size; i++) { | ||
vec[i] = arr[i]; | ||
} | ||
return vec; | ||
} | ||
extern "C" bool return_opposite(bool input) { return !input; } | ||
extern "C" char **createArrayString(char **arr, int size) { | ||
char **vec = (char **)malloc((size) * sizeof(char *)); | ||
for (int i = 0; i < size; i++) { | ||
vec[i] = arr[i]; | ||
} | ||
return vec; | ||
} | ||
``` | ||
typedef struct Person { | ||
const char *name; | ||
int age; | ||
double doubleProps; | ||
char **stringArray; | ||
double *doubleArray; | ||
int *i32Array; | ||
} Person; | ||
### compile c code to dynamic library | ||
extern "C" const Person *getStruct(const Person *person) { | ||
printf("Name: %s\n", person->name); | ||
printf("Age: %d\n", person->age); | ||
printf("doubleProps: %f \n", person->doubleProps); | ||
printf("stringArray: %s\n", person->stringArray[0]); | ||
printf("stringArray: %s\n", person->stringArray[1]); | ||
printf("doubleArray: %f\n", person->doubleArray[0]); | ||
printf("doubleArray: %f\n", person->doubleArray[1]); | ||
printf("i32Array: %d\n", person->i32Array[0]); | ||
return person; | ||
} | ||
``` | ||
```bash | ||
@@ -150,4 +111,8 @@ $ g++ -dynamiclib -o libsum.so cpp/sum.cpp # macos | ||
### call dynamic library by ffi-rs | ||
Then can use `ffi-rs` invoke the dynamic library file contains functions. | ||
### initialization | ||
```js | ||
@@ -176,2 +141,9 @@ const { equal } = require('assert') | ||
``` | ||
### Basic Types | ||
`number|string|boolean|double|void` are basic types | ||
```js | ||
const c = "foo" | ||
@@ -204,2 +176,46 @@ const d = c.repeat(200) | ||
})) | ||
const bool_val = true | ||
equal(!bool_val, load({ | ||
library: 'libsum', | ||
funcName: 'return_opposite', | ||
retType: DataType.Boolean, | ||
paramsType: [DataType.Boolean], | ||
paramsValue: [bool_val], | ||
})) | ||
``` | ||
### Array | ||
Use `arrayConstructor` to specify array type with legal length which is important. | ||
If the length is incorrect, program maybe exit abnormally | ||
```cpp | ||
extern "C" int *createArrayi32(const int *arr, int size) { | ||
int *vec = (int *)malloc((size) * sizeof(int)); | ||
for (int i = 0; i < size; i++) { | ||
vec[i] = arr[i]; | ||
} | ||
return vec; | ||
} | ||
extern "C" double *createArrayDouble(const double *arr, int size) { | ||
double *vec = (double *)malloc((size) * sizeof(double)); | ||
for (int i = 0; i < size; i++) { | ||
vec[i] = arr[i]; | ||
} | ||
return vec; | ||
} | ||
extern "C" char **createArrayString(char **arr, int size) { | ||
char **vec = (char **)malloc((size) * sizeof(char *)); | ||
for (int i = 0; i < size; i++) { | ||
vec[i] = arr[i]; | ||
} | ||
return vec; | ||
} | ||
``` | ||
```js | ||
let bigArr = new Array(100).fill(100) | ||
@@ -231,17 +247,65 @@ deepStrictEqual(bigArr, load({ | ||
})) | ||
const bool_val = true | ||
equal(!bool_val, load({ | ||
library: 'libsum', | ||
funcName: 'return_opposite', | ||
retType: DataType.Boolean, | ||
paramsType: [DataType.Boolean], | ||
paramsValue: [bool_val], | ||
})) | ||
``` | ||
### Struct | ||
For create a c struct or get a c struct as a return type, you need to define the types of the parameters strictly in the order in which the fields of the c structure are defined. | ||
```cpp | ||
typedef struct Person { | ||
const char *name; | ||
int age; | ||
double doubleProps; | ||
char **stringArray; | ||
double *doubleArray; | ||
int *i32Array; | ||
} Person; | ||
extern "C" const Person *getStruct(const Person *person) { | ||
return person; | ||
} | ||
extern "C" Person *createPerson() { | ||
Person *person = (Person *)malloc(sizeof(Person)); | ||
// Allocate and initialize doubleArray | ||
person->doubleArray = (double *)malloc(sizeof(double) * 3); | ||
person->doubleArray[0] = 1.0; | ||
person->doubleArray[1] = 2.0; | ||
person->doubleArray[2] = 3.0; | ||
// Initialize age and doubleProps | ||
person->age = 30; | ||
person->doubleProps = 1.23; | ||
// Allocate and initialize name | ||
person->name = strdup("John Doe"); | ||
person->stringArray = (char **)malloc(sizeof(char *) * 2); | ||
person->stringArray[0] = strdup("Hello"); | ||
person->stringArray[1] = strdup("World"); | ||
person->i32Array = (int *)malloc(sizeof(int) * 3); | ||
person->i32Array[0] = 1; | ||
person->i32Array[1] = 2; | ||
person->i32Array[2] = 3; | ||
person->testnum = 123; | ||
person->boolTrue = true; | ||
person->boolFalse = false; | ||
return person; | ||
} | ||
``` | ||
```js | ||
const person = { | ||
name: 'tom', | ||
doubleArray: [1.1, 2.2, 3.3], | ||
age: 23, | ||
doubleProps: 1.1, | ||
name: 'tom', | ||
stringArray: ["foo", "bar"], | ||
doubleArray: [1.1, 2.2, 3.3], | ||
i32Array: [1, 2, 3, 4] | ||
i32Array: [1, 2, 3, 4], | ||
testnum: 32, | ||
boolTrue: true, | ||
boolFalse: false | ||
} | ||
@@ -252,16 +316,22 @@ const personObj = load({ | ||
retType: { | ||
name: DataType.String, | ||
doubleArray: arrayConstructor({ type: DataType.DoubleArray, length: person.doubleArray.length }), | ||
age: DataType.I32, | ||
doubleProps: DataType.Double, | ||
name: DataType.String, | ||
stringArray: arrayConstructor({ type: DataType.StringArray, length: person.stringArray.length }), | ||
doubleArray: arrayConstructor({ type: DataType.DoubleArray, length: person.doubleArray.length }), | ||
i32Array: arrayConstructor({ type: DataType.I32Array, length: person.i32Array.length }), | ||
testnum: DataType.I32, | ||
boolTrue: DataType.Boolean, | ||
boolFalse: DataType.Boolean, | ||
}, | ||
paramsType: [{ | ||
name: DataType.String, | ||
age: DataType.I32, | ||
doubleProps: DataType.Double, | ||
name: DataType.String, | ||
stringArray: DataType.StringArray, | ||
doubleArray: DataType.DoubleArray, | ||
i32Array: DataType.I32Array, | ||
testnum: DataType.I32, | ||
boolTrue: DataType.Boolean, | ||
boolFalse: DataType.Boolean, | ||
}], | ||
@@ -271,3 +341,85 @@ paramsValue: [person] | ||
deepStrictEqual(person, personObj) | ||
const p = load({ | ||
library: 'libsum', | ||
funcName: 'createPerson', | ||
retType: { | ||
doubleArray: arrayConstructor({ type: DataType.DoubleArray, length: 3 }), | ||
age: DataType.I32, | ||
doubleProps: DataType.Double, | ||
name: DataType.String, | ||
stringArray: arrayConstructor({ type: DataType.StringArray, length: 2 }), | ||
i32Array: arrayConstructor({ type: DataType.I32Array, length: 3 }), | ||
testnum: DataType.I32, | ||
boolTrue: DataType.Boolean, | ||
boolFalse: DataType.Boolean, | ||
}, | ||
paramsType: [], | ||
paramsValue: [] | ||
}) | ||
console.log('createPerson', p) | ||
deepStrictEqual(p, { | ||
doubleArray: [1, 2, 3], | ||
age: 30, | ||
doubleProps: 1.23, | ||
name: 'John Doe', | ||
stringArray: ['Hello', 'World'], | ||
i32Array: [1, 2, 3], | ||
testnum: 123, | ||
boolTrue: true, | ||
boolFalse: false | ||
}) | ||
``` | ||
## Function | ||
`ffi-rs` supports passing js function to c, like this | ||
```cpp | ||
typedef void (*FunctionPointer)(int a, bool b, char *c, char **d, int *e); | ||
extern "C" void callFunction(FunctionPointer func) { | ||
printf("callFunction\n"); | ||
int a = 100; | ||
bool b = false; | ||
char *c = (char *)malloc(14 * sizeof(char)); | ||
strcpy(c, "Hello, World!"); | ||
char **stringArray = (char **)malloc(sizeof(char *) * 2); | ||
stringArray[0] = strdup("Hello"); | ||
stringArray[1] = strdup("world"); | ||
int *i32Array = (int *)malloc(sizeof(int) * 3); | ||
i32Array[0] = 101; | ||
i32Array[1] = 202; | ||
i32Array[2] = 303; | ||
func(a, b, c, stringArray, i32Array); | ||
} | ||
``` | ||
Corresponds to the code above,you can use `ffi-rs` like | ||
```js | ||
const func = (a, b, c, d, e) => { | ||
console.log('func params', a, b, c, d, e) | ||
equal(a, 100) | ||
equal(b, false) | ||
equal(c, 'Hello, World!') | ||
deepStrictEqual(d, ['Hello', 'world']) | ||
deepStrictEqual(e, [101, 202, 303]) | ||
} | ||
load({ | ||
library: 'libsum', | ||
funcName: 'callFunction', | ||
retType: DataType.Void, | ||
paramsType: [funcConstructor({ | ||
paramsType: [DataType.I32, DataType.Boolean, DataType.String, | ||
arrayConstructor({ type: DataType.StringArray, length: 2 }), | ||
arrayConstructor({ type: DataType.I32Array, length: 3 }), | ||
], | ||
retType: DataType.Void | ||
})], | ||
paramsValue: [func], | ||
}) | ||
``` | ||
The function parameters supports type are all in the example above, we will support more types in the future |
Sorry, the diff of this file is not supported yet
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
566344
417