Calling C function with Bitmap data from Flutter - c

My mission is to take a picture using the camera, send the pixels to C function, and provide a message to the user if the function returns an indication of a problematic image (e.g.: poor focus, picture too dark, etc).
I want to call a C function and send a pointer to the function which includes the pixels (and other parameters like image width/height). The idea is to use the C code and check the image quality.
The C code is ready. I found samples how to bind it into Flutter. But I do not know how to get the Bitmap data and pixels and send them to the C function.

You can do that binding to native code using dart:ffi.
Imagine that you have a C function that returns the sum of two numbers with this code:
#include <stdint.h>
extern "C" __attribute__((visibility("default"))) __attribute__((used))
int32_t native_add(int32_t x, int32_t y) {
return x + y;
}
And this C Makefile
cmake_minimum_required(VERSION 3.4.1) # for example
add_library( native_add
# Sets the library as a shared library.
SHARED
# Provides a relative path to your source file(s).
../native_add.cpp )
Now you need to encapsulate this CMake file into the externalNativeBuild inside build.gradle, this could be an example:
android {
// ...
externalNativeBuild {
// Encapsulates your CMake build configurations.
cmake {
// Provides a relative path to your CMake build script.
path "CMakeLists.txt"
}
}
// ...
}
Now that you have the library and you have encapsulated the code you can load the code using the FFI library like this:
import 'dart:ffi'; // For FFI
import 'dart:io'; // For Platform.isX
final DynamicLibrary nativeAddLib = Platform.isAndroid
? DynamicLibrary.open("libnative_add.so")
: DynamicLibrary.process();
And with a handle to an enclosing library you can resolve the native_add symbol as we do here:
final int Function(int x, int y) nativeAdd =
nativeAddLib
.lookup<NativeFunction<Int32 Function(Int32, Int32)>>("native_add")
.asFunction();
Now you could use it on your application calling the nativeAdd function, here you have an example:
body: Center(
child: Text('1 + 2 == ${nativeAdd(1, 2)}'),
),
You can learn how flutter native code binding works in the following url: flutter docs c-interop

Related

Using multiple Objective-C header files in Swift project

I would like to use the AAPLRendererUtils and AAPLMathUtilities files from the following Apple sample code in a Swift project.
I have created a bridging header where I have imported "APPLMathUtilities.h" and it works just fine. However, when I try to import "AAPLRendererUtils.h" I run into issues.
AAPLRendererUtils.h is a header-only file and does not follow the usual Objective-C #interface and #implementation pattern.
AAPLRendererUtils.h also imports APPLMathUtilities.h so maybe this dependency is an issue?
#import "AAPLMathUtilities.h"
//----------------------------------------------------------------------------------------
struct Camera
{
vector_float3 position;
vector_float3 target;
float rotation;
float aspectRatio; // width/height
float fovVert_Half; // half of vertical field of view, in radians
float distanceNear;
float distanceFar;
matrix_float4x4 GetViewMatrix () const
{
return matrix_look_at_left_hand(position, target, (vector_float3){0,1,0});
}
matrix_float4x4 GetProjectionMatrix_LH () const
{
return matrix_perspective_left_hand (
fovVert_Half * 2.f,
aspectRatio,
distanceNear,
distanceFar);
}
};
Interestingly, if I comment out the function declarations the code runs but if I leave them in I get the following error:
field 'GetViewMatrix' declared as a function
Since you cannot have functions in structs in C am I correct in thinking that Xcode is interpreting this file as a C file?
This is not a C header, it is a C++ header. The files that this gets included in, in the sample document, all have the ".mm" extension which is Objective-C++. C++ does allow structs to have methods (it's basically a class where all the members are public, IIRC). I know a couple of years ago, Swift was not very good at working with C++ files. I don't know if that's changed. You could probably separate the methods from the struct to make a C file and a header if you are diligent enough.

How develop PostgreSQL extension inluding PostGIS library

I'm NOT a C expert.
That been said building PostgreSQL extension using or not C is very powerful.
99% of the time I work also using PostGIS, and extensions too, but here is the problem:
Cannot properly include what is needed, I've played using
#include "../postgis_config.h"
#include "liblwgeom.h"
#include "lwgeom_pg.h"
but cannot have a proper result without recompiling whole PostGIS... and so create a derived version.
PostGIS should be dependency for the lib I've in mind, so I need something that link to it, if present or catch error, while compiling my lib...
Currently I'm resolving using the PostgreSQL's #include <utils/geo_decls.h>
so creating PostgreSQL functions interfaces that:
translates a PostGIS feature to a PostgreSQL base geo type
pass the results to my C libs
works with those very base types (loosing any support from powerful PostGIS lib )
send result to the function that translate back to PostGIS.
Just go give a simple idea of what I'm doing now:
mylib.c
#include "postgres.h"
#include "fmgr.h"
#include <utils/geo_decls.h>
#include "utils/builtins.h"
Datum pg_xytile_to_box(PG_FUNCTION_ARGS)
{
int x, y, zoom;
struct tile_box box;
BOX *pg_box = (BOX *) palloc(sizeof(BOX));
x = PG_GETARG_INT64(0);
y = PG_GETARG_INT64(1);
zoom = PG_GETARG_INT32(2);
if ( xytile_to_box(&box, x, y, zoom) != 0 )
{
pfree(pg_box);
PG_RETURN_NULL();
}
pg_box->low.x = box.w;
pg_box->low.y = box.s;
pg_box->high.x = box.e;
pg_box->high.y = box.n;
PG_RETURN_BOX_P(pg_box);
}
PG_FUNCTION_INFO_V1(pg_xytile_to_box);
extension_code.sql
CREATE OR REPLACE FUNCTION _xytile_to_box(x int, y int, zoom int default 11) RETURNS box
AS 'MODULE_PATHNAME', 'pg_xytile_to_box'
LANGUAGE C IMMUTABLE STRICT;
CREATE OR REPLACE FUNCTION xtile_to_geom(xtile int, ytile int, zoom int default 11) returns geometry(polygon, 4326)
language plpgsql security definer as $FUNC$
BEGIN
return (
select st_setsrid((ST_MakeBox2D(b[0]::geometry(point), b[1]::geometry(point)))::geometry(polygon), 4326) as t
from _xytile_to_box(xtile, ytile, zoom) as b
);
END; $FUNC$;
There is a way to instruct a Makefile to find and add PostGIS to the imports?
There is something better?
PostGIS doesn't seem to have a public C API, so you won't be able to link to the PostGIS libraries directly.
My recommendation is to call the PostGIS SQL functions from your C code by using the Server Programming Interface (SPI). An alternative is calling PostGIS functions directly with the function-call interface in include/fmgr.h, which would be faster, but requires that you first look up the functions in the catalog.

Setting file path in imported C function inside Swift Framework

I am trying to use C library source files inside my Cocoa Framework which has function named
void swe_set_ephe_path(char *path);
Which will basically be
swe_set_ephe_path(”C:\\SWEPH\\EPHE”);
for windows.
This library contains other data files which only work after this function is set.
When imported to Swift the function looks like this
swe_set_ephe_path(path: UnsafeMutablePointer<Int8!>)
Since i want to bundle up all the data files in framework and use it in my application, i have done something like this
public class SwissEphemeris {
public init() {
let path = Bundle.main.bundlePath
let swePath = UnsafeMutablePointer<Int8>(mutating: (path as NSString).utf8String)
swe_set_ephe_path(swePath)
}
}
But it seems it's not working and the functions which needs data to be searched in files are not able to operate.
If anybody interested to look into Swiss library documentation, check here for the link,
https://www.astro.com/swisseph/swephprg.htm#_Toc505244836
There are two problems:
First, the resource files are in the “Resources” subdirectory of the framework, not in the top-level framework directory. You can obtain a path to that directory with
let resourcePath = Bundle(identifier: "com.Abhi.SwissFramework")!.resourcePath!
or with
let resourcePath = Bundle(for: type(of: self)).resourcePath!
I suggest to force-unwrap the optionals because you know that the bundle and the resources directory exist. A failure would indicate a build problem which should be detected early.
Second, the C function takes a char * argument even though it does not mutate the passed string. Here you can use the approach from UnsafeMutablePointer<Int8> from String in Swift:
resourcePath.withCString {
swe_set_ephe_path(UnsafeMutablePointer(mutating: $0))
}
Even better: use the dedicated method withUnsafeFileSystemRepresentation() to get the file system representation of the resource path as a C string:
let resourceURL = Bundle(for: type(of: self)).resourceURL!
resourceURL.withUnsafeFileSystemRepresentation {
swe_set_ephe_path(UnsafeMutablePointer(mutating: $0))
}

Configurable custom code

Our customer provided source code has portions of code that will be executed based on tool type. A sample code portion is given below. The function has common portions and tool specific(hardware platform) portions. The code is written in C and runs in VxWorks. Addition or deletion of new tool type has code modification. The customer wants addition or deletion new tool type with minimal code change and testing effort
int vsp_recv(char *const recv_text)
{
int rc = 0;
const int type = get_tool_type();
// Common Code
if (MODEL_CR == type)
{
rc = beamoff(recv_text);
}
else
{
rc = vsp_set(recv_text);
}
return(rc);
}
Is it the right technique to separate the code to two methods as given below, keep them in separate source files and define separate make files to generate tool specific binary? Is there any better ways to do this?
Tool type MODEL_CR code
int vsp_recv_tool_speccific(char *const recv_text)
{
return beamoff(recv_text);
}
Tool type MODEL_CV code
int vsp_recv_tool_speccific(char *const recv_text)
{
return vsp_set(recv_text);
}
Refactored method
int vsp_recv(char *const recv_text)
{
int rc = 0;
const int type = get_tool_type();
// Common Code
rc = vsp_recv_tool_speccific(recv_text);
}
Define a shared library for each tool and a configuration file that defines what functions get called for each tool. Load the shared libraries at startup and provide a signal catcher to reload if the configuration file changes.
the OPs question (and posted code) says that 3 places will need to be modified.
the function: get_tool_type()
the header file with the definitions of MODEL_CV, MODEL_CR, etc
the if-then-else list.
were it me, I would implement a table of function pointers, have get_tool_type() return an index into that table. Then all the if/then/else code would become a single statement that invokes a function from the table.
Then any updates would be additions to the table, modifications to 'get_too_type(), and the additional functions likebeam_off()`
The loss of a tool type would not require any code change.
the addition of a tool type would require appending an entry to the table, mod to get_tool_type() to recognize the new tool, and the new function to process the new tool type.
Of course, this could result in code that is never executed.

c: Convert ipv6 address to string at compile time

This is a longshot, but I'm wondering if there are any tricks to convert a constant ipv6 address string into two 64 bit integers at compile time. (this is on an embedded system, and thus runtime and memory are both valuable commodities). Ideally the code would look something like:
const uint64_t addr[2] = { IPV6_TO_UINT64S("::ffff:192.168.1.1") };
which would produce:
const uint64_t addr[2] = { 0x0000000000000000ULL, 0x0000ffffc0a80101ULL };
For this sort of thing I'd recommend writing a template header file (not C++ templates, but fill-in-the-blank templates), putting the human-readable values in a config file, and using a small program to fill in the blanks.
For example, the config file might be in JSON. (This is obviously overkill for a single value, I'm just showing the technique.)
{
"addr": "::ffff:192.168.1.1"
}
You could use an existing template language, or make up your own. For something as simple as a C header file, you can get away with something very simple.
const uint64_t addr[2] = { %%addr%% };
And the code to read the config and process the template simple in a ubiquitous scripting language like Ruby.
#!/usr/bin/env ruby
require 'json'
template, config_file = ARGV[0..1]
# Load the config file
config = JSON.load( File.new(config_file) )
# Ensure missing config variables throw an error
config.default_proc = proc do |hash, key|
throw "Config key '#{key}' is missing from #{config_file}"
end
# ...do whatever processing on the config variables you want...
# Fill in the template.
IO.foreach(template) { |line|
puts line.gsub(/%%(.*?)%%/) { config[$1] }
}
I employ this technique in the y2038 library. It has to probe the system to determine the limits of time.h, then encode those limits into a custom header file. munge_config reads the configuration values (from the build system, not from a JSON config, but the result is the same: a hash), and fills in the template. This is the time64_limits.h.in template and an example of a resulting time64_limits.h header file.

Resources