flutter how to create an dart:ffi struct reference - flutter

I created a struct with dart:ffi.
import 'dart:ffi';
import 'package:ffi/ffi.dart';
class TestStruct extends Struct{
external Pointer<Utf8> strText;
#Int32()
external int nNum;
#Bool()
external bool bIsTrue;
//contstruct
TestStruct(String str, int number, bool state){
strText = str as Pointer<Utf8>;
nNum = number as int;
bIsTrue = state as bool;
}
}
I want to create a reference of TestStruct and use it. So I wrote the code.
TestStruct test = TestStruct("Text", 10, true);
but this is an error
Subclasses of 'Struct' and 'Union' are backed by native memory, and can't be instantiated by a generative constructor.
Try allocating it via allocation, or load from a 'Pointer'.
I tried searching with the api documentation, but I didn't understand. Do you know how to create a struct as a reference?? thank you.

Example:
class InAddr extends Struct {
factory InAddr.allocate(int sAddr) =>
calloc<InAddr>().ref
..sAddr = sAddr;
#Uint32()
external int sAddr;
}
You can allocate this with calloc function
final Pointer<InAddr> inAddress = calloc<InAddr>();
And free the pointer with
calloc.free(inAddress);

While I am late to the party, writing a complete example so that it may be helpful for others new to the FFI scene.
If this is the dart representative struct (from C) -
import 'dart:ffi';
import 'package:ffi/ffi.dart';
class TestStruct extends Struct{
#Int32()
external int nNum;
#Bool()
external bool bIsTrue;
// IMPORTANT: DO NOT DEFINE A CONSTRUCTOR since struct/union are natively allocated
}
You can instantiate from dart using ffi.Pointer like below.
// my_native_helper.dart
final dynamicLibrary = ... ; // load .so/process
void some_function() {
final Pointer<TestStruct > inAddress = calloc<TestStruct >();
inAddress.ref.nNum= 1234;
inAddress.ref.bIsTrue = false;
// ffigen generated method replicating C extern function
// To auto generate this, define the C signature in a header file
dynamicLibrary.receiveFromDart(inAddress);
calloc.free(inAddress);
}
The C method will look like below.
extern "C" void recieveFromDart(TestStruct* structPtr) {
cout << structPtr->nNum << "/" << structPtr->bIsTrue << endl;
}

According to the doc you can't create instances of Struct classes:
https://api.flutter.dev/flutter/dart-ffi/Struct-class.html
However, you typically would need pointers. So you can come up with something like that:
static Pointer<InAddr> allocate(int sAddr) {
final pointer = calloc<InAddr>();
pointer.ref.sAddr = sAddr;
return pointer;
}

Related

Initialize a final variable in a constructor in Dart. Two ways but only one of them work? [duplicate]

This question already has an answer here:
Is there a difference in how member variables are initialized in Dart?
(1 answer)
Closed 1 year ago.
I'm trying to understand the following example where I try to initialize a final variable in a constructor.
1st example - works
void main() {
Test example = new Test(1,2);
print(example.a); //print gives 1
}
class Test
{
final int a;
int b;
Test(this.a, this.b);
}
2nd example doesn't work
void main() {
Test example = new Test(1,2);
print(example.a); //compiler throws an error
}
class Test
{
final int a;
int b;
Test(int a, int b){
this.a = a;
this.b = b;
}
}
and when i remove final then it works again
void main() {
Test example = new Test(1,2);
print(example.a); //print gives 1
}
class Test
{
int a;
int b;
Test(int a, int b){
this.a = a;
this.b = b;
}
}
what is the difference between the constructor in the 1st and the 2nd constructor why final initialization works with the first and doesn't with the 2nd.
Can anyone explain that to me please?
THanks
You cannot instantiate final fields in the constructor body.
Instance variables can be final, in which case they must be set exactly once. Initialize final, non-late instance variables at declaration, using a constructor parameter, or using a constructor’s initializer list:
Declare a constructor by creating a function with the same name as
its class (plus, optionally, an additional identifier as described in
Named constructors). The most common form of constructor, the
generative constructor, creates a new instance of a class
syntax in the constructor (described in https://www.dartlang.org/guides/language/language-tour#constructors):

swift send struct data from class to instance

I made a static library in C language.
The functions of this library are as follows.
Save the callback function point in a global variable
The callback function has a parameter of the struct structure.
The library transmits struct data by calling the callback function to the library user at a specific moment.
The source for this is:
static library source
// ---------------------------------------------
// Static Library
// ---------------------------------------------
typedef struct
{
unsigned long m_Data1;
unsigned long m_Data2;
unsigned long m_Data3;
} SEND_DATA;
//
typedef int (*ReportCallbackProc)(SEND_DATA *pSendData);
//
static ReportCallbackProc gReportFunc = NULL;
static Period = 0;
// Set callback function pointer to gloval variable
int SetReport(ReportCallbackProc func, int period)
{
gReportFunc = func;
Period = period;
return(1);
}
// Send data to Application of library
void Report()
{
.............
SEND_DATA sendData;
sendData.m_Data1 = 1;
sendData.m_Data2 = 2;
sendData.m_Data3 = 3;
int rc = gReportFunc(&sendData);
if (rc != 1)
{
printf("gRealtimeReportFunc failed: status=[%d]\n", rc);
}
.....
}
application of this library
// ---------------------------------------------
// Application of Static Library
// ---------------------------------------------
void handle_report (SEND_DATA *pSendData)
{
printf("Report called");
printf("m_Data1 = %ld ", pSendData->m_Data1);
printf("m_Data2 = %ld ", pSendData->m_Data2);
printf("m_Data3 = %ld ", pSendData->m_Data3);
}
void main()
{
SetReport (&handle_report, period);
}
I want to make the above source in swift. Currently, I am trying to implement while studying swift.
However, it is not an easy problem and asks for help.
I tried creating and implementing closure usage and classes, but it was never easy.
Can you provide similar swift code?
Can you tell me how to implement it?

How do you import a variable from the main actions panel to a class file?

I've searched long for this one, but nobody seems to give a clear answer. I'm a beginner, and I want to import a variable from the main "F9" actions panel into a class file so it can read it (example: in main .fla file, I have a variable var myNumber:Number = 1; how would I import it into a class file so the program can read it?)
You can create a “Document Class”. In this class you can place your variable. Where will you use myNumber variable?
package {
import flash.display.MovieClip;
public class Main extends MovieClip {
public var myNumber:Number = 1;
public function Main()
{ }
}
}
You can "share" your variable when you create an instance of your class by passing it in the class constructor, or using any other public function.
Take this example :
MyClass.as :
package {
public class MyClass {
private var number:int;
public function MyClass(num:int = 0) {
// assign the value of the variable to a private one for a later use
this.number = num;
// use directly the value of the variable
trace('the number is passed in the constructor : ' + num);
}
public function set_number(num:int):void {
// assign the value of the variable to a private one for a later use
this.number = num;
}
public function use_number(num:int):void {
// use the value of the variable
trace(num + ' x ' + num + ' = ' + (num * num));
}
}
}
test.fla :
import MyClass;
var my_number:int = 1234;
var my_class:MyClass = new MyClass(my_number); // using the class constructor
my_class.set_number(my_number); // using a function to set a private var value
my_class.use_number(my_number); // using a function to do some operations
Hope that can help.

What are function typedefs / function-type aliases in Dart?

I have read the description, and I understand that it is a function-type alias.
A typedef, or function-type alias, gives a function type a name that you can use when declaring fields and return types. A typedef retains type information when a function type is assigned to a variable.
http://www.dartlang.org/docs/spec/latest/dart-language-specification.html#kix.yyd520hand9j
But how do I use it? Why declaring fields with a function-type? When do I use it? What problem does it solve?
I think I need one or two real code examples.
A common usage pattern of typedef in Dart is defining a callback interface. For example:
typedef void LoggerOutputFunction(String msg);
class Logger {
LoggerOutputFunction out;
Logger() {
out = print;
}
void log(String msg) {
out(msg);
}
}
void timestampLoggerOutputFunction(String msg) {
String timeStamp = new Date.now().toString();
print('${timeStamp}: $msg');
}
void main() {
Logger l = new Logger();
l.log('Hello World');
l.out = timestampLoggerOutputFunction;
l.log('Hello World');
}
Running the above sample yields the following output:
Hello World
2012-09-22 10:19:15.139: Hello World
The typedef line says that LoggerOutputFunction takes a String parameter and returns void.
timestampLoggerOutputFunction matches that definition and thus can be assigned to the out field.
Let me know if you need another example.
Dart 1.24 introduces a new typedef syntax to also support generic functions. The previous syntax is still supported.
typedef F = List<T> Function<T>(T);
For more details see https://github.com/dart-lang/sdk/blob/master/docs/language/informal/generic-function-type-alias.md
Function types can also be specified inline
void foo<T, S>(T Function(int, S) aFunction) {...}
See also https://www.dartlang.org/guides/language/language-tour#typedefs
typedef LoggerOutputFunction = void Function(String msg);
this looks much more clear than previous version
Just slightly modified answer, according to the latest typedef syntax, The example could be updated to:
typedef LoggerOutputFunction = void Function(String msg);
class Logger {
LoggerOutputFunction out;
Logger() {
out = print;
}
void log(String msg) {
out(msg);
}
}
void timestampLoggerOutputFunction(String msg) {
String timeStamp = new Date.now().toString();
print('${timeStamp}: $msg');
}
void main() {
Logger l = new Logger();
l.log('Hello World');
l.out = timestampLoggerOutputFunction;
l.log('Hello World');
}
Typedef in Dart is used to create a user-defined function (alias) for other application functions,
Syntax: typedef function_name (parameters);
With the help of a typedef, we can also assign a variable to a function.
Syntax:typedef variable_name = function_name;
After assigning the variable, if we have to invoke it then we go as:
Syntax: variable_name(parameters);
Example:
// Defining alias name
typedef MainFunction(int a, int b);
functionOne(int a, int b) {
print("This is FunctionOne");
print("$a and $b are lucky numbers !!");
}
functionTwo(int a, int b) {
print("This is FunctionTwo");
print("$a + $b is equal to ${a + b}.");
}
// Main Function
void main() {
// use alias
MainFunction number = functionOne;
number(1, 2);
number = functionTwo;
// Calling number
number(3, 4);
}
Output:
This is FunctionOne
1 and 2 are lucky numbers !!
This is FunctionTwo
3 + 4 is equal to 7
Since dart version 2.13 you can use typedef not only with functions but with every object you want.
Eg this code is now perfectly valid:
typedef IntList = List<int>;
IntList il = [1, 2, 3];
For more details see updated info:
https://dart.dev/guides/language/language-tour#typedefs
https://www.tutorialspoint.com/dart_programming/dart_programming_typedef.htm
typedef ManyOperation(int firstNo , int secondNo); //function signature
Add(int firstNo,int second){
print("Add result is ${firstNo+second}");
}
Subtract(int firstNo,int second){
print("Subtract result is ${firstNo-second}");
}
Divide(int firstNo,int second){
print("Divide result is ${firstNo/second}");
}
Calculator(int a,int b ,ManyOperation oper){
print("Inside calculator");
oper(a,b);
}
main(){
Calculator(5,5,Add);
Calculator(5,5,Subtract);
Calculator(5,5,Divide);
}

unmanaged var as member of managed class c++

I'm novice in .net c++ and trying to create class looking like:
public ref class Klient
{
public:
Klient(){}
// zmienne
static DWORD klienty[41][2];
static int i = 1;
static DWORD* pid;
static HANDLE* handle;
//funkcje
};
but MSV says that:
error C4368: cannot define 'klienty' as a member of managed 'Klient': mixed types are not supported
What's wrong with this code?
You can have .NET basic data types as members of your managed class (static int i), or pointers to anything unmanaged (DWORD* pid, HANDLE* handle), but you're not allowed to have an unmanaged object directly, and the array of integers counts as an unmanaged object for this purpose.
Since the only item giving you a problem here is the unmanaged array, you could switch it to a managed array.
public ref class Klient
{
public:
Klient(){}
// zmienne
static array<DWORD,2>^ klienty = gcnew array<DWORD,2>(41,2);
static int i = 1;
static DWORD* pid;
static HANDLE* handle;
//funkcje
};
Or, you can declare a unmanaged class, put whatever you need to in there, and have a pointer to it from the managed class. (If you do this in a non-static context, don't forget to delete the unmanaged memory from your finalizer.)
public class HolderOfUnmanagedStuff
{
public:
DWORD klienty[41][2];
int i;
DWORD* pid;
HANDLE* handle;
HolderOfUnmanagedStuff()
{
i = 1;
}
};
public ref class Klient
{
public:
Klient(){}
// zmienne
static HolderOfUnmanagedStuff* unmanagedStuff = new HolderOfUnmanagedStuff();
//funkcje
};