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?
Related
I have the following code in c++/cli
`
public ref class Form1 : public System::Windows::Forms::Form
{
public:
Form1(void)
{
InitializeComponent();
//
//TODO: Konstruktorcode hier hinzufügen.
//
delegate int fooProc(UInt16);
}
...
public: void goTest(int x) { // declared in header
fooProc^ managed = gcnew fooProc(this, &Form1::foo);
IntPtr stubPointer = Marshal::GetFunctionPointerForDelegate(managed);
slave[x].module = static_cast<int(*)(unsigned short)>(stubPointer.ToPointer());
...
}
}
public: int foo(unsigned short test) {
Form1::label1->Text = "Hello success !";
...
return 1; // seems to not return to library function ( Run-Time Check Failure #0 - The value of ESP was not properly saved ...)
}
`
then in a static library with native code there is a function which calls the method 'foo' thru the pointer slave[x].module
as following:
int nativefoo(...) {
...
anyStruct[x].module(x); // struct defined in header
...
return 0;
}
The code crashes in method on return. Probably mismatch in calling conventions.
I have no idea how to solve this issue.
I only tried to alter and match the calling conventions. From __clrcall to __cdecl but no affect.
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;
}
I'm trying to write a C++/CLI forms application that creates a lot of buttons at runtime: I have a vector of strings and for each string a button is being created:
std::vector<std::string> strings;
/*
string being initialized with values from file
*/
for ( std::vector<std::string>::iterator it = heroes.begin(); it != heroes.end(); ++it ) {
Button ^ button = gcnew Button;
/*
button being customized depending on the string
*/
buttonPannel->Controls->Add(button);
}
Now what I want to do is add an event handler for each button in a way that the string used to customize the button would be passed to handling method.
In c# I would have written something like
button->Click += new EventHandler((sender, args) => button_Click(s, e, *it));
How do I achieve this in C++/CLI?
You could do the exact equivalent of your C# code, but I'd rather make use of an existing property on the Button class to hold the extra data you need.
In this case, the Tag property seems appropriate: its purpose is to hold any extra data you need that is closely associated with the control, so this seems on-point for your string that drives the program logic. (You may need to make it a managed String^ object, rather than a std::string, but that's an easy conversion.)
void Form1::CreateButtons()
{
for (std::vector<std::string>::iterator it = heroes.begin(); it != heroes.end(); ++it)
{
Button ^ button = gcnew Button;
button->Tag = marshal_as<String^>(*it);
button->Click += gcnew EventHandler(this, &Form1::button_Click);
buttonPanel->Controls->Add(button);
}
}
void Form1::button_Click(Object^ sender, EventArgs^ e)
{
Control^ senderControl = dynamic_cast<Control^>(sender);
String^ heroName = nullptr;
if(senderControl != nullptr)
heroName = dynamic_cast<String^>(senderControl->Tag);
if(heroName == nullptr)
{
// Something went wrong. Bail out.
return;
}
// ...
}
If you really do want to do the equivalent of your C# code: Your C# lambda is doing variable capture on the it variable. We can do variable capture in C++/CLI, it's just a lot more manual.
(Note: Your C# example is capturing the iterator, not the string, not sure if that's what was intended. I wrote this to capture the string object instead.)
ref class EventHandlerStringCapture
{
public:
EventHandlerStringCapture(std::string str,
Action<Object^, EventArgs^, std::string>^ handler)
{
this->str = str;
this->handler = handler;
}
void eventHandler(Object^ sender, EventArgs^ e)
{
this->handler(sender, e, this->str);
}
private:
std::string str;
Func<Object^, EventArgs^, std::string>^ handler;
}
void Form1::CreateButtons()
{
for (std::vector<std::string>::iterator it = heroes.begin(); it != heroes.end(); ++it)
{
Button ^ button = gcnew Button;
// The variable to capture.
std::string str = *it;
// The actual event handler: a method in the current class.
Action<Object^, EventArgs^, std::string>^ actualHandler =
gcnew Action<Object^, EventArgs^, std::string>(this, &Form1::button_Click);
// Pass both the variable to capture and the
// actual event handler to a helper object.
EventHandlerStringCapture^ ehsc =
gcnew EventHandlerStringCapture(str, actualHandler);
// Grab the two-parameter event handler from the helper object,
// and make that the click handler.
button->Click +=
gcnew EventHandler(ehsc, &EventHandlerStringCapture::eventHandler);
buttonPanel->Controls->Add(button);
}
}
void Form1::button_Click(Object^ sender, EventArgs^ e, std::string heroName)
{
// ...
}
(Note: I'm not at a compiler, so there may be syntax errors.)
Obviously, using an existing property on the button object is simpler, but that's the C++/CLI equivalent to what the C# compiler does behind the scenes.
I am new to device drivers and I was learning this container_of and dev_get_drvdata and came across this driver.I removed some partof this driver so as to make it compact.
static void tsl4531_polling_worker(struct work_struct *work)
{
u8 buf[2];
struct tsl4531_data *data = container_of(to_delayed_work(work),
struct tsl4531_data, work);
mutex_lock(&data->update_lock);
buf[0] = DEVICE_LIGHT;
buf[1] = GET_REQUEST;
sam4l_send_request(data->pdata.sam4l,2,buf);
mutex_unlock(&data->update_lock);
}
static ssize_t store_enable_value(struct device *dev,struct device_attribute *devattr,const char *buf,size_t count){
struct tsl4531_data *data = dev_get_drvdata(dev);
if((buf[0] == '1') && (!tsl4531_enabled)) {
schedule_delayed_work(&data->work, msecs_to_jiffies(50));
tsl4531_enabled = 1;
} else if (buf[0] == '0'){
tsl4531_enabled = 0;
cancel_delayed_work_sync(&data->work);
tsl4531_lux = 0;
}
return count;
}
static DEVICE_ATTR(enable,S_IRUGO | S_IWUGO,
show_enable_value, store_enable_value );
static struct attribute *tsl4531_attributes[] = {
&dev_attr_lux_show.attr,
&dev_attr_enable.attr,
NULL
};
static const struct attribute_group tsl4531_attr_group = {
.attrs = tsl4531_attributes,
};
void tsl4531_callback_fun(struct work_struct *work)
{
struct tsl4531_data *chip = container_of(work,struct tsl4531_data,
pdata.work.work);
tsl4531_lux = chip->pdata.response[2];//Need to check on which response index we get lux value
input_report_abs(tsl4531_dev, ABS_X,tsl4531_lux);
input_sync(tsl4531_dev);
schedule_delayed_work(&chip->work, msecs_to_jiffies(1500));
}
static int __devinit tsl4531_probe(struct platform_device *pdev){
struct tsl4531_data *chip;
int err=0;
chip = kzalloc(sizeof(struct tsl4531_data), GFP_KERNEL);
if (!chip){
dev_dbg(&pdev->dev, "memory not allocated for tsl4531 light sensor module.\n");
return -ENOMEM;
}
dev_set_drvdata(&pdev->dev,chip);//here we give address in chip to struct device
tsl4531_dev=input_allocate_device();
if(!tsl4531_dev) {
dev_dbg(&pdev->dev, "memory not allocated for tsl4531_dev.\n");
return -ENOMEM;
}
err=input_register_device(tsl4531_dev);
if(err){
dev_dbg(&pdev->dev, "input register poll the device failed ... \n");
goto err_reg_poll;
}
mutex_init(&chip->update_lock);
err = sysfs_create_group(&pdev->dev.kobj,&tsl4531_attr_group);
if (err){
dev_dbg(&pdev->dev, "creating sysfs group for tsl4531 sensor module failed.\n");
goto exit_err;
}
INIT_DELAYED_WORK(&chip->work, tsl4531_polling_worker);
INIT_DELAYED_WORK(&chip->pdata.work,tsl4531_callback_fun);
chip->pdata.dev_id = DEVICE_LIGHT;
return 0;
return err;
}
static int __devexit tsl4531_remove(struct platform_device *pdev){
struct tsl4531_data *data = dev_get_drvdata(&pdev->dev);
cancel_delayed_work_sync(&data->work);
cancel_delayed_work(&data->pdata.work);
sysfs_remove_group(&pdev->dev.kobj, &tsl4531_attr_group);
unregister_sam4l_client(&data->pdata);
kfree(data);
return 0;
}
static const struct platform_device_id tsl4531_id[] = {
{ "tsl45317", 0 },
{ }
};
static struct platform_driver tsl4531_driver = {
.driver = {
.owner = THIS_MODULE,
.name = "tsl45317",
},
.probe = tsl4531_probe,
.remove = tsl4531_remove,
.suspend = tsl4531_suspend,
.resume = tsl4531_resume,
.id_table = tsl4531_id,
};
static int __init tsl4531_init(void){
return platform_driver_register(&tsl4531_driver);
}
static void __exit tsl4531_exit(void){
platform_driver_unregister(&tsl4531_driver);
}
I have few doubts regarding working of container_of and dev_get_drvdata
1)in the polling_worker function we can see one container_of macro which fetches the address to the original structure and assigned to struct tsl4531_data *data;
2)in the probe function we can see one call to dev_set_drvdata and in store_enable_value and tsl4531 dev_get_drvdata.
Isn't both container_of and dev_set and dev_get doing same things here?
container_of and dev_set, dev_get are different. But yes, the intention might be the same. Both are actually used to retrieve the pointer (usually to the private data structure of the device).
container_of() actually does a reverse mapping. It does the opposite of &struct_base->member operation. In the previous operation you have the pointer to the base of the structure and need the address of one of its member. While, container_of takes in the address of the member and returns the base address. In the tsl4531_polling_worker() function, it has the member's address and using container_of it is getting the base address of the structure (struct tsl4531_data)
dev_set_drvdata() is generally used to preserve a pointer's address, such that it could be retrieved later using dev_get_drvdata(). Unlike reverse mapping, the functions stores and loads the address from a pointer of type void * (refer http://lxr.free-electrons.com/source/drivers/base/dd.c#L595)
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);
}