How to call a native C function from Flutter? - c

I want to call 'hello_world' function from Flutter.
#include <stdio.h>
#include "hello.h"
__attribute__((visibility("default"))) __attribute__((used))
int main()
{
hello_world();
return 0;
}
void hello_world()
{
printf("Hello World\n");
}
I have tried this way in my plugin.dart:
final DynamicLibrary helloLib = Platform.isAndroid
? DynamicLibrary.open("libhello.so")
: DynamicLibrary.process();
final void Function() hello =
helloLib
.lookup<NativeFunction<Void Function()>>("hello_world")
.asFunction();
In my main.dart file I tried this way:
body: Center(
child: Text('Running on: ${hello}'),
But it shows void instead of showing the result. How to solve this problem?
Thanks in advance.

Related

How Use QTimer Command

I have a problem in using QTimer command.
I dont have any syntax error, but i have 2 error in qglobal.h and qobjectdefs_impl.h and i dont understand them.
MainWindow.cpp
MainWindow::MainWindow(QWidget *parent) :
QMainWindow(parent),
ui(new Ui::MainWindow)
{
ui->setupUi(this);
}
void MainWindow::updatewindow()
{
Mat frame;
capture >> frame;
cvtColor(frame, frame, cv::COLOR_BGR2RGB);
QImage image((uchar*)frame.data, frame.cols, frame.rows, frame.step, QImage::Format_RGB888);
QPixmap temp_img = QPixmap::fromImage(image);
ui->label2->setPixmap(temp_img);
}
void MainWindow::on_pushload_clicked()
{
QTimer *timer = new QTimer(this);
connect(timer, &QTimer::timeout, this, SLOT(updatewindow()));
timer->start(20);
}
I have a problem in using QTimer command.
I dont have any syntax error, but i have 2 error in qglobal.h and qobjectdefs_impl.h and i dont understand them.
and mainwindow.h:
#ifndef MAINWINDOW_H
#define MAINWINDOW_H
#include <QMainWindow>
#include <QPixmap>
#include <QTimer>
#include <iostream>
#include <opencv2/core/core.hpp>
#include <opencv2/opencv.hpp>
#include <opencv2/imgproc.hpp>
#include <opencv2/highgui.hpp>
namespace Ui {
class MainWindow;
}
class MainWindow : public QMainWindow
{
Q_OBJECT
public:
explicit MainWindow(QWidget *parent = 0);
~MainWindow();
private:
QPixmap Iblackwhite,IMG_Color{};
QImage image {};
cv::VideoCapture capture{};
private slots:
void updatewindow();
void on_pushload_clicked();
private:
Ui::MainWindow *ui;
};
#endif // MAINWINDOW_H
please help me to solve my problem.
Use &MainWindow::updateWindow instead of SLOT(updatewindow()).

How to get the value of global static variables having same name in 2 separate files in C program

I'm trying to execute a program in C. While executing I'm getting the same value for global static variables(static int data) with the same name declared in 2 separate files program1.c and program2.c where the main() function is in program1.c The actual answer should be apple = 2 and orange = 3 but the static int data variable is getting overridden by oranges_set(3) function call. Could anyone please let me know what could be the issue? Thanks in advance.
program1.c
#include <stdio.h>
#include "program2.c"
void apples_set(int value);
int apples_get();
static int data;
void oranges_set(int value)
{
data = value;
}
int oranges_get()
{
printf("Value of oranges = %d \n",data);
return data;
}
int main(){
apples_set(2);
oranges_set(3);
printf("Apple = %d and Orange = %d",apples_get(),oranges_get());
return 0;
}
========================================================
program2.c
static int data;
void apples_set(int value)
{
data = value;
}
int apples_get()
{
printf("Value of apples = %d \n",data);
return data;
}
These are not separate files, because you include the one in the other. This is equivalent to copying the entire content of program2.c and pasting it place of the #include "program2.c" line in program1.c.
For this to work correctly, you need to compile the files as separate object files and then link those together.

LLVM Pass to insert an external function call to LLVM bitcode

I am writing an LLVM pass to instrument a C source program. I want to insert a function call before each branch instruction which calls an external function like this :
void print(int x){
printf("x = %d\n", x);
return;
}
I want to link this external function to C source code using llvm-link tool and then instrument the code using opt tool.
Ths pass that I have implemented is like this:
#include "llvm/Pass.h"
#include "llvm/IR/Module.h"
#include "llvm/IR/Function.h"
#include "llvm/Support/raw_ostream.h"
#include "llvm/IR/Type.h"
#include "llvm/IR/Instructions.h"
#include "llvm/IR/Instruction.h"
#include "llvm/IR/LLVMContext.h"
#include "llvm/Support/raw_ostream.h"
#include "llvm/IR/IRBuilder.h"
#include <vector>
using namespace llvm;
namespace{
struct ir_instrumentation : public ModulePass{
static char ID;
Function *monitor;
ir_instrumentation() : ModulePass(ID) {}
virtual bool runOnModule(Module &M)
{
std::vector<Type *> args;
args.push_back(Type::getInt32Ty(M.getContext()));
ArrayRef<Type*> argsRef(args);
FunctionType *FT = FunctionType::get(Type::getVoidTy(M.getContext()), args, false);
Constant* myFunc = M.getOrInsertFunction("print", FT, NULL);
minitor = cast<Function>(myFunc);
for(Module::iterator F = M.begin(), E = M.end(); F!= E; ++F)
{
for(Function::iterator BB = F->begin(), E = F->end(); BB != E; ++BB)
{
for(BasicBlock::iterator BI = BB->begin(), BE = BB->end(); BI != BE; ++BI)
{
if(isa<BranchInst>(&(*BI)) )
{
errs() << "found a branch instruction!\n";
ArrayRef< Value* > arguments(ConstantInt::get(Type::getInt32Ty(M.getContext()), 5, true));
Instruction *newInst = CallInst::Create(monitor, arguments, "");
BB->getInstList().insert(BI, newInst);
errs() << "Inserted the function!\n";
}
}
}
}
return true;
}
};
char ir_instrumentation::ID = 0;
static RegisterPass<ir_instrumentation> X("ir-instrumentation", "LLVM IR Instrumentation Pass");
}
LLVM is configured and built fine with this pass but when I use opt, I get this error :
opt: /llvm/lib/IR/Type.cpp:281:
llvm::FunctionType::FunctionType(llvm::Type*, llvm::ArrayRefllvm::Type*, bool):
Assertion `isValidReturnType(Result) && "invalid return type for function"' failed.
I think the problem is something like mismatching between the function type that I have declared and the external function (like the context).
LLVM version: LLVM version 7.0.0svn
Until now I have not solved the problem.
Thanks
I could finally solve this problem and successfully instrument LLVM bitcode. After a lot of trouble with function getOrInsertFunction, I found out it is not really necessary to use this method in my case. I just simply changed my pass to this:
#include "llvm/Pass.h"
#include "llvm/IR/Module.h"
#include "llvm/IR/Function.h"
#include "llvm/Support/raw_ostream.h"
#include "llvm/IR/Type.h"
#include "llvm/IR/Instructions.h"
#include "llvm/IR/Instruction.h"
#include "llvm/IR/LLVMContext.h"
#include "llvm/Support/raw_ostream.h"
#include "llvm/IR/IRBuilder.h"
#include <vector>
using namespace llvm;
namespace{
struct ir_instrumentation : public ModulePass{
static char ID;
Function *monitor;
ir_instrumentation() : ModulePass(ID) {}
virtual bool runOnModule(Module &M)
{
errs() << "====----- Entered Module " << M.getName() << ".\n";
int counter = 0;
for(Module::iterator F = M.begin(), E = M.end(); F!= E; ++F)
{
errs() << "Function name: " << F->getName() << ".\n";
if(F->getName() == "print"){
monitor = cast<Function>(F);
continue;
}
for(Function::iterator BB = F->begin(), E = F->end(); BB != E; ++BB)
{
for(BasicBlock::iterator BI = BB->begin(), BE = BB->end(); BI != BE; ++BI)
{
if(isa<BranchInst>(&(*BI)) )
{
errs() << "found a brach instruction!\n";
ArrayRef< Value* > arguments(ConstantInt::get(Type::getInt32Ty(M.getContext()), counter, true));
counter++;
Instruction *newInst = CallInst::Create(monitor, arguments, "");
BB->getInstList().insert(BI, newInst);
errs() << "Inserted the function!\n";
}
}
}
}
return true;
}
};
char ir_instrumentation::ID = 0;
static RegisterPass<ir_instrumentation> X("ir-instrumentation", "LLVM IR Instrumentation Pass");
}
As I know the name of the external function, I can simply find it through iterating over all functions of module and then use it in the desired way.
Obviously the problem was caused by calling module->getOrInsertFunction and the function type. My experience says that this method is more useful when you want to insert a new function and declare the prototype of your own function. Using it to get an existing function is challenging (e.g. setting the right prototype, ...)
Thanks

C++ program crashed when loading array of objects

Hello i'm trying to fill an array of objects from a text file in c++ , but i have a crash every time i run the program. I'm i at the right direction here? Is there any more eficient way to do it?
main.cpp
#include <iostream>
#include <string>
#include <stdio.h>
#include <fstream>
#include "Item.h"
using namespace std;
void readItems(FILE *products, Item pList[]);
FILE *products;
int main()
{
Item pList[5];
readItems(products,pList);
return 0;
}
void readItems(FILE *products, Item pList[]){
products = fopen("data.txt", "r");
int i = 0;
fread(&pList[i], sizeof(pList), 1, products);
while (!feof(products))
{
i++;
fread (&pList[i], sizeof(pList), 1, products);
}
fclose(products);
}
Item.cpp
#include "Item.h"
#include <stdio.h>
#include <string>
#include <conio.h>
#include <iostream>
using namespace std;
Item::Item()
{
code = 0;
description = "";
price = 0;
}
Item::Item(int code1,string description1,float price1)
{
code = code1;
description = description1;
price = price1;
}
void Item::printData(){
cout<<endl<<"Code:"<<code<<"\tName:"<<description<<"\tPrice:"<<price;
}
void Item::setData(int code1,string description1,float price1){
code = code1;
description = description1;
price = price1;
}
int Item::getCode(){
return code;
}
float Item::getPrice(){
return price;
}
Item::~Item()
{
//dtor
}
The new code is like that , but it prints a set of some chars of the txt file with some weird symbols .
void readItems(FILE *fin, Item list[]){
int i=0;
products = fopen("items.txt","r");
fread(&list[i],sizeof(list[i]),1,products);
list[i].printData();
while(!feof(products) && i<5){
fread(&list[i],sizeof(list[i]),1,products);
list[i].printData();
i++;
}
fclose(products);
}
Try replacing
while (!feof(products))
{
i++;
fread (&pList[i], sizeof(pList), 1, products);
}
with
while (!feof(products) && (i < 5))
{
i++;
fread (&pList[i], sizeof(pList), 1, products);
}

shared library how to link to a symbol?

I have:
car.cc
#include "car.h"
#include <iostream>
using namespace std;
extern "C" Car* create_object()
{
return new Car;
}
Car::Car() {
this->maxGear = 2;
this->currentGear = 1;
this->speed = 0;
}
void Car::shift(int gear) {
if (gear < 1 || gear > maxGear) {
return;
}
currentGear = gear;
}
void Car::brake() {
speed -= (5 * this->getCurrentGear());
std::cout<<"THE SPEED IS:" <<speed<<std::endl;
}
extern "C" void destroy_object( Car* object )
{
delete object;
}
car.h
#ifndef VEHICLES_CAR_H
#define VEHICLES_CAR_H
// A very simple car class
class Car {
public:
Car();
void shift(int gear);
void accelerate();
void brake();
private:
int maxGear;
int currentGear;
int speed;
};
#endif /* VEHICLES_CAR_H */
test.cc
#include "/home/car.h"
#include <dlfcn.h>
#include <stdio.h>
#include <stdlib.h>
#include <iostream>
using namespace std;
int main()
{
/* on Linux, use "./myclass.so" */
void* handle = dlopen("/usr/lib/libCarTest.so", RTLD_LAZY);
int (*result)(int);
if (!handle)
{
}
/*dlsym(handle,"accelerate");
cout<<"IN HERE: "<<endl;
dlsym(handle,"brake");
dlclose(handle);*/
Car* (*create)();
void (*destroy)(Car*);
dlerror();
create = (Car* (*)())dlsym(handle, "create_object");
destroy = (void (*)(Car*))dlsym(handle, "destroy_object");
Car* carr = (Car*)create();
carr->brake();
destroy( carr );
dlclose(handle);
/*
Car carr;
carr.brake();
* compilation g++ test.cpp -o tst /path/libcar.so
*/
return 0;
}
After creating libMyLib.so and install it in /usr/lib i've tried to compile test.cc using: g++ test.cc -o tst -ldl. WHY do i need to include -lMyLib? is there a way to compile the code without libMyLib.so? Secondly why dlsym(handle,"brake") is not working? If i change dlsym (Car* (*).... with dlsym(handle,"brake") i get nothing. why?
Appreciate
WHY do i need to include -lMyLib?
Because you need to link to the Car::brake method.
Secondly why dlsym(handle,"brake") is not working?
Because there is no brake symbol. The method Car::brake has a complicated mangled (implementation-defined) name. You can see this in the output of nm -D.
AFAIK, you can solve it by
making all the methods of Car virtual (they will be called through a pointer, so no linking will be needed)
doing it the old C way, ie. export a free function brake() that would call the Car::brake method from the .so
making all the public methods of Car inline and defining them in the header.
emulating the virtual table approach (as we do it in C)
Combining the last two approaches:
class Car {
public:
void brake() { brake_impl(this); }
private:
void (*brake_impl)(Car*);
void do_brake(); // this would be the actual implementation
Car() : brake_impl([] (Car* c){ c->do_brake(); }) { ... }
};
Of course you could split the implementation and the interface so it's not such a mess.

Resources