Write first part of FFI library and header and use it in C app

Currently macOS only compilation
This commit is contained in:
Jan-Erik Rediger 2019-04-26 14:15:14 +02:00
Родитель 2a7f01c868
Коммит 52979046bd
5 изменённых файлов: 121 добавлений и 3 удалений

1
.gitignore поставляемый
Просмотреть файл

@ -19,3 +19,4 @@ xcuserdata
Cartfile.resolved
Carthage
glean-core/data
glean_app

Просмотреть файл

@ -0,0 +1,9 @@
objects = glean_app.c ../../../target/debug/libglean_ffi.dylib
headers = glean.h
glean_app: $(objects) $(headers)
$(CC) $(CFLAGS) -o $@ $(objects)
../../../target/debug/libglean_ffi.dylib: ../src/lib.rs
cargo build

Просмотреть файл

@ -0,0 +1,23 @@
#include <stdint.h>
struct ExternError {
int32_t code;
char *message; // note: nullable
};
void glean_initialize();
uint8_t glean_is_upload_enabled();
uint64_t glean_new_boolean_metric(const char* name, const char* category, struct ExternError *err);
uint64_t glean_new_counter_metric(const char* name, const char* category, struct ExternError *err);
uint64_t glean_counter_add(uint64_t, uint32_t amount, struct ExternError *err);
uint64_t glean_new_string_metric(const char* name, const char* category, struct ExternError *err);
void glean_set_upload_enabled(uint8_t flag);
char *glean_ping_collect(const char* ping_name, struct ExternError *error);
void glean_str_free(char* ptr);

Просмотреть файл

@ -0,0 +1,26 @@
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include "glean.h"
int main(void)
{
glean_initialize();
printf("Glean upload enabled? %d\n", glean_is_upload_enabled());
glean_set_upload_enabled(0);
printf("Glean upload enabled? %d\n", glean_is_upload_enabled());
glean_set_upload_enabled(1);
struct ExternError err;
uint64_t metric = glean_new_counter_metric("counter", "local", &err);
printf("Created counter: %llu\n", metric);
glean_counter_add(metric, 2, &err);
char *payload = glean_ping_collect("core", &err);
printf("Payload:\n%s\n", payload);
glean_str_free(payload);
return 0;
}

Просмотреть файл

@ -1,37 +1,96 @@
use std::os::raw::c_char;
use lazy_static::lazy_static;
use ffi_support::{
IntoFfi,
FfiStr,
ConcurrentHandleMap,
ExternError,
define_handle_map_deleter,
define_string_destructor,
call_with_output,
};
use glean_core::{
Glean,
CommonMetricData,
metrics::BooleanMetric,
metrics::*,
};
lazy_static! {
static ref BOOLEAN_METRICS: ConcurrentHandleMap<BooleanMetric> = ConcurrentHandleMap::new();
static ref STRING_METRICS: ConcurrentHandleMap<StringMetric> = ConcurrentHandleMap::new();
static ref COUNTER_METRICS: ConcurrentHandleMap<CounterMetric> = ConcurrentHandleMap::new();
}
#[no_mangle]
pub extern fn glean_initialize() {
Glean::initialize();
Glean::singleton().initialize();
}
#[no_mangle]
pub extern fn glean_new_boolean_metric(name: FfiStr<'_>, category: FfiStr<'_>, err: &mut ExternError) -> u64 {
pub extern fn glean_is_upload_enabled() -> u8 {
Glean::singleton().is_upload_enabled().into_ffi_value()
}
#[no_mangle]
pub extern fn glean_set_upload_enabled(flag: u8) {
let flag = flag != 0;
Glean::singleton().set_upload_enabled(flag);
}
#[no_mangle]
pub extern fn glean_new_boolean_metric(name: FfiStr, category: FfiStr, err: &mut ExternError) -> u64 {
BOOLEAN_METRICS.insert_with_output(err, || {
BooleanMetric::new(CommonMetricData {
name: name.into_string(),
category: category.into_string(),
send_in_pings: vec!["core".into()],
.. Default::default()
})
})
}
#[no_mangle]
pub extern fn glean_new_string_metric(name: FfiStr, category: FfiStr, err: &mut ExternError) -> u64 {
STRING_METRICS.insert_with_output(err, || {
StringMetric::new(CommonMetricData {
name: name.into_string(),
category: category.into_string(),
send_in_pings: vec!["core".into()],
.. Default::default()
})
})
}
#[no_mangle]
pub extern fn glean_new_counter_metric(name: FfiStr, category: FfiStr, err: &mut ExternError) -> u64 {
COUNTER_METRICS.insert_with_output(err, || {
CounterMetric::new(CommonMetricData {
name: name.into_string(),
category: category.into_string(),
send_in_pings: vec!["core".into()],
.. Default::default()
})
})
}
#[no_mangle]
pub extern fn glean_counter_add(metric_id: u64, amount: u32, error: &mut ExternError) {
COUNTER_METRICS.call_with_output(error, metric_id, |metric| {
metric.add(amount);
()
})
}
#[no_mangle]
pub extern fn glean_ping_collect(ping_name: FfiStr, error: &mut ExternError) -> *mut c_char {
call_with_output(error, || {
let ping_maker = glean_core::ping::PingMaker::new();
let ping = ping_maker.collect_string(ping_name.as_str());
ping
})
}
define_handle_map_deleter!(BOOLEAN_METRICS, glean_destroy_boolean_metric);
define_string_destructor!(glean_str_free);