Trying to interface with a C library that takes a struct with a bunch of pointers to functions it calls at various points.
something like this:
struct callbacks {
int (*foo)(int);
int (*bar)(int);
}
int set_callbacks(callbacks *cbs);
I can make my callbacks:
sub foo-callback(int32 --> int32) {...}
sub bar-callback(int32 --> int32) {...}
It would be cool if this worked:
class Callbacks is repr<CStruct>
{
has &.foo (int32 --> int32);
has &.bar (int32 --> int32);
}
but it doesn't. I'm trying to do something with:
class Callbacks is repr<CStruct>
{
has Pointer $.foo;
has Pointer $.bar;
}
and set those to nativecast(Pointer, &foo-callback) or some such, but I can't
seem to force them in there.
Is there any way to do this beyond writing a little C function that takes all the Perl 6 function pointers and plugging them in the structure in C?
I still can't find an official way to do this, but I figured out a work-around.
Declare a version of sprintf that takes a function pointer of the right type (so it will set up the calling shim correctly), but cheat and have sprintf just give me back the pointer as a number (%lld) I can stuff in the Pointer.
class Callbacks is repr<CStruct>
{
has Pointer $.foo;
has Pointer $.bar;
sub sprintf(Blob, Str, & (int32 --> int32) --> int32) is native {}
submethod BUILD(:&foo, :&bar)
{
my $buf = buf8.allocate(20);
my $len = sprintf($buf, "%lld", &foo);
$!foo := Pointer.new($buf.subbuf(^$len).decode.Int);
$len = sprintf($buf, "%lld", &bar);
$!bar := Pointer.new($buf.subbuf(^$len).decode.Int);
}
}
sub foo-callback(int32 $x --> int32) {...}
sub bar-callback(int32 $x --> int32) {...}
my $callbacks = Callbacks.new(foo => &foo-callback,
bar => &bar-callback);
If you have multiple callbacks with different signatures, just declare a sprintf for each C calling signature you need, e.g.:
sub sprintf-ii(Blob, Str, & (int32 --> int32) --> int32)
is native is symbol('sprintf') {}
sub sprintf-isi(Blob, Str, & (int32, Str --> int32) --> int32)
is native is symbol('sprintf') {}
and call the right sprintf-* for each callback pointer you need.
There is probably an easier way than going back and forth with the pointer to number to string to number to pointer, but this does the trick for now.
Related
Is there any way to pass a function pointer to an Objective C method, and then have that method modify the function pointer to point at a C function somewhere else?
Creating a method that accepts a function pointer is simple enough:
- (void)doSomethingWithFunctionPointer:(void(*)(/* args go here */))functionPointer;
I can then call that function inside doSomethingWithFunctionPointer simply by calling:
if (functionPointer)
{
functionPointer();
}
But what if I actually wanted to change the functionPointer to point at something else within doSomethingWithFunctionPointer, so that any code outside that method can then call the changed function pointer to call the function that doSomethingWithFunctionPointer point it to?
I know this is probably a prime example of how not to do things in Objective C (especially considering we've got blocks and what not). It's more just curiosity at this point. It almost sounds like I'd need a function pointer pointer, but I'm not sure how that would work, if it's even possible.
This can be done using pointers to function pointers. Perhaps the most readable way to do it is to typedef your function pointer, like this:
typedef void (*FunPtr)(int a, float b);
Then use a pointer of that typedef-ed type to assign in a function, like this:
void foo(int a, float b) {
printf("FOO : %d %f\n", a, b);
}
void bar(int a, float b) {
printf("BAR : %d %f\n", a, b);
}
// This function receives a pointer to function pointer
void assign(int n, FunPtr *ptr) {
if (n == 0) {
*ptr = foo;
} else {
*ptr = bar;
}
}
Here is how you call assign from your code:
int main(void) {
FunPtr f;
assign(0, &f);
f(10, 20.5);
assign(1, &f);
f(10, 20.5);
return 0;
}
Demo.
Note: You are right about blocks in Objective-C greatly reducing the need for direct use of function pointers. However, you can use a similar typedef trick with pointers to blocks.
I have a struct and I would like it to be initialised with some sensible default values.
Typically, the thing to do here is to use a constructor but since go isn't really OOP in the traditional sense these aren't true objects and it has no constructors.
I have noticed the init method but that is at the package level. Is there something else similar that can be used at the struct level?
If not what is the accepted best practice for this type of thing in Go?
There are some equivalents of constructors for when the zero values can't make sensible default values or for when some parameter is necessary for the struct initialization.
Supposing you have a struct like this :
type Thing struct {
Name string
Num int
}
then, if the zero values aren't fitting, you would typically construct an instance with a NewThing function returning a pointer :
func NewThing(someParameter string) *Thing {
p := new(Thing)
p.Name = someParameter
p.Num = 33 // <- a very sensible default value
return p
}
When your struct is simple enough, you can use this condensed construct :
func NewThing(someParameter string) *Thing {
return &Thing{someParameter, 33}
}
If you don't want to return a pointer, then a practice is to call the function makeThing instead of NewThing :
func makeThing(name string) Thing {
return Thing{name, 33}
}
Reference : Allocation with new in Effective Go.
There are actually two accepted best practices:
Make the zero value of your struct a sensible default. (While this looks strange to most people coming from "traditional" oop it often works and is really convenient).
Provide a function func New() YourTyp or if you have several such types in your package functions func NewYourType1() YourType1 and so on.
Document if a zero value of your type is usable or not (in which case it has to be set up by one of the New... functions. (For the "traditionalist" oops: Someone who does not read the documentation won't be able to use your types properly, even if he cannot create objects in undefined states.)
Go has objects. Objects can have constructors (although not automatic constructors). And finally, Go is an OOP language (data types have methods attached, but admittedly there are endless definitions of what OOP is.)
Nevertheless, the accepted best practice is to write zero or more constructors for your types.
As #dystroy posted his answer before I finished this answer, let me just add an alternative version of his example constructor, which I would probably write instead as:
func NewThing(someParameter string) *Thing {
return &Thing{someParameter, 33} // <- 33: a very sensible default value
}
The reason I want to show you this version is that pretty often "inline" literals can be used instead of a "constructor" call.
a := NewThing("foo")
b := &Thing{"foo", 33}
Now *a == *b.
There are no default constructors in Go, but you can declare methods for any type. You could make it a habit to declare a method called "Init". Not sure if how this relates to best practices, but it helps keep names short without loosing clarity.
package main
import "fmt"
type Thing struct {
Name string
Num int
}
func (t *Thing) Init(name string, num int) {
t.Name = name
t.Num = num
}
func main() {
t := new(Thing)
t.Init("Hello", 5)
fmt.Printf("%s: %d\n", t.Name, t.Num)
}
The result is:
Hello: 5
I like the explanation from this blog post:
The function New is a Go convention for packages that create a core type or different types for use by the application developer. Look at how New is defined and implemented in log.go, bufio.go and cypto.go:
log.go
// New creates a new Logger. The out variable sets the
// destination to which log data will be written.
// The prefix appears at the beginning of each generated log line.
// The flag argument defines the logging properties.
func New(out io.Writer, prefix string, flag int) * Logger {
return &Logger{out: out, prefix: prefix, flag: flag}
}
bufio.go
// NewReader returns a new Reader whose buffer has the default size.
func NewReader(rd io.Reader) * Reader {
return NewReaderSize(rd, defaultBufSize)
}
crypto.go
// New returns a new hash.Hash calculating the given hash function. New panics
// if the hash function is not linked into the binary.
func (h Hash) New() hash.Hash {
if h > 0 && h < maxHash {
f := hashes[h]
if f != nil {
return f()
}
}
panic("crypto: requested hash function is unavailable")
}
Since each package acts as a namespace, every package can have their own version of New. In bufio.go multiple types can be created, so there is no standalone New function. Here you will find functions like NewReader and NewWriter.
In Go, a constructor can be implemented using a function that returns a pointer to a modified structure.
type Colors struct {
R byte
G byte
B byte
}
// Constructor
func NewColors (r, g, b byte) *Colors {
return &Color{R:r, G:g, B:b}
}
For weak dependencies and better abstraction, the constructor does not return a pointer to a structure, but an interface that this structure implements.
type Painter interface {
paintMethod1() byte
paintMethod2(byte) byte
}
type Colors struct {
R byte
G byte
B byte
}
// Constructor return intreface
func NewColors(r, g, b byte) Painter {
return &Color{R: r, G: g, B: b}
}
func (c *Colors) paintMethod1() byte {
return c.R
}
func (c *Colors) paintMethod2(b byte) byte {
return c.B = b
}
another way is;
package person
type Person struct {
Name string
Old int
}
func New(name string, old int) *Person {
// set only specific field value with field key
return &Person{
Name: name,
}
}
If you want to force the factory function usage, name your struct (your class) with the first character in lowercase. Then, it won't be possible to instantiate directly the struct, the factory method will be required.
This visibility based on first character lower/upper case work also for struct field and for the function/method. If you don't want to allow external access, use lower case.
Golang is not OOP language in its official documents.
All fields of Golang struct has a determined value(not like c/c++), so constructor function is not so necessary as cpp.
If you need assign some fields some special values, use factory functions.
Golang's community suggest New.. pattern names.
I am new to go. I have a pattern taken from other languages, that have constructors. And will work in go.
Create an init method.
Make the init method an (object) once routine. It only runs the first time it is called (per object).
func (d *my_struct) Init (){
//once
if !d.is_inited {
d.is_inited = true
d.value1 = 7
d.value2 = 6
}
}
Call init at the top of every method of this class.
This pattern is also useful, when you need late initialisation (constructor is too early).
Advantages: it hides all the complexity in the class, clients don't need to do anything.
Disadvantages: you must remember to call Init at the top of every method of the class.
Edit :
I have an ATL simple object MyATLObject, having only one method :
STDMETHODIMP CMyATLObject::EVAL( DOUBLE* x, long AddressOfFunc )
{
*x = toto<FCTPTR>(*((FCTPTR) AddressOfFunc)) ;
return S_OK;
}
where toto is a template function defined by
#pragma once
template<typename F>
double toto( F f )
{
return f(0.0) ;
}
and where FCTPTR is defined as
typedef double (__stdcall * FCTPTR)( double );
My ATL method consume double x for storing the result of toto, and long AddressOfFunc which is the AddressOf of a VBA function.
This passing VBA function to ATL methods by Address. it is quite awful. How would it be able to do the same - passing VBA functions - to ATL method otherwise, for instance by defining an interface on the ATL side ?
Thank you very much.
//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
First version of my question :
I am actually doing the following : creating an ATL/COM project, adding a "simple ATL object" called MyATLObject to it with :
1) in the idl file :
interface IMyATLObject : IDispatch{
[id(1), helpstring("method EVAL")] HRESULT EVAL(DOUBLE* x, long AddressOfFunc) ;
};
2 in the MyATLObject.h file :
an
#include "MyStupidEvaluator.h"
and a
typedef double (__stdcall * FCTPTR)( double );
outside the class, and in the class
public:
STDMETHOD(EVAL)(DOUBLE* x, long AddressOfFunc) ;
and finally in the MyATLObject.cpp file :
STDMETHODIMP CMyATLObject::EVAL( DOUBLE* x, long AddressOfFunc )
{
*x = toto<FCTPTR>(*((FCTPTR) AddressOfFunc)) ;
return S_OK;
}
MyStupidEvaluator.h contains :
#pragma once
template<typename F>
double toto( F f )
{
return f(0.0) ;
}
This is just a template function that returns the value at zero of any function object, that is a typename (or a class) admitting a () operator.
Now, this gives to me, after compilation, a dll.
That's all for the c++ part. Now, I'm referencing this dll in VBA and in VBA :
a) I define a function
Public Function F(ByVal x As Double) As Double
F = x * x - 2 * x + 1
End Function
b) and a sub
Public Sub Draft1()
Dim ENGINE As MyTestProjectLib.MyATLObject
Set ENGINE = New MyTestProjectLib.MyATLObject
Dim x As Double
x = 0#
Call ENGINE.EVAL(x, AddressOf F)
Sheets("Test1").Range("Value_at_0").Offset(0, 0).Value = x
End Sub
c) Executing this sub will give to me, in the range V"alue_at_0" (just a cell here) of the sheet "Test1" the value at 0.0 of the function F.
I'm always working like this : the toto template function is trivial here (evaluation at 0.0) but in general it could be a numerical integration routine, or a root finding routine for which c++ is needed for quickness ; I'm alwas passing VBA functions through their addresses, thanks to the AddressOf VBA keyword : this gives me a long that I pass to my ATL method EVAL, I convert this long in function pointer (FCTPTR) p, and I apply my routine "toto" to *p, which gives a double to me, that I pass back to my ATL method.
That's cool, everything works, but... I find this awful !!! And really inelegant. That's why I would like to do the following :
design "somehow" an interface on the ATL side, a
interface IMyFunction : IDispatch
that would be implemented (through VBA's implements) in VBA by a VBA class VBAClass1, and pass an instance of that VBA class to a new version of my former VBA method for performing the evaluation at 0.0.
My problem is : I'm not an expert at all in ATL, nor in interface creating : I've succeeded in doing real stupid/trivial things in interface creating, ok, but I really don't see how to design the interface doing what I want to do, that is :
an interface in ATL (which will by definition have only methods, by ATL construction !) that would have "something" playing the role of a member of a class, member keeping track of a VBA function still to be passed to him through an ATL method.
Any help would be greatly appreciated, folks.
It's my first time here, so sorry per advance if the message is not in the perfect/optimal form.
Thank you in advance.
Raph
You should reconsider everything you have around AddressOfFunc parameter and callback address. When you design COM interface and you would like to provide a callback, you need to pass a callable COM interface pointer as an argument (related discussion), so that COM class would call its methods back - the would require your VBA class implements this interface (related question). If you prefer to not implement interfaces on VBA side, another option is to design ATL COM class with events (connection points), so that COM class would fire an event and your caller would handle it doing the callback activity there.
Plain address of function is not going to work here, you should have suspected it when you had to cast things to make them even compile.
UPD. This provides sample on how to call back VB code: Three ways to implement VBScript (VB6, VBA) callback from C++/ATL class
i'm a novel developer and i would like to know in yours experience what is the better approach when your building class methods, and if there is not a better approach, how balance your decisions with respect to:
Pass as arguments a big object that contains most of the variables needed for the method.
Pass the more atomic individuals variables possibles, with the consequences of generate methods with big signatures.
What is better for a code that is going to evolve? and what do you think is a reasonable number of arguments?
I would argue strongly in favor of passing around an object, if the commonality in the sets pf arguments allows it.
Why?
Because X% of effort goes to maintain existing code and it's a LOT harder to add new parameters - especially in methods that chain-call each other and pass those new parameters - than to add a property to an object.
Please note that this doesn't have to be a CLASS per se, in a sense of having methods. Merely a storage container (either a heterogeneous map/dictionary, or for type safety, a struct in C-type langages that support it).
Example (I'll use pseudocode, feel free which language(s) it's based on):
First, let's see old and new code using argument lists
Old code:
function f1(arg1, arg2, arg3, arg4, arg5) {
res = f2(arg1, arg2, arg3, arg4);
}
function f2(arg1, arg2, arg3, arg4) {
res = f3(arg1, arg2, arg4);
}
function f3(arg1, arg2, arg4) {
res = f4(arg1, arg4);
}
function f4(arg1, arg4) {
return arg1 + arg4;
}
New code (need to add arg6 in f4()):
function f1(arg1, arg2, arg3, arg4, arg5, arg6) { // changed line
res = f2(arg1, arg2, arg3, arg4, arg6); // changed line
}
function f2(arg1, arg2, arg3, arg4, arg6) { // changed line
res = f3(arg1, arg2, arg4, arg6); // changed line
}
function f3(arg1, arg2, arg4, arg6) { // changed line
res = f4(arg1, arg4, arg6); // changed line
}
function f4(arg1, arg4, arg6) { // changed line
return arg1 + arg4 + arg6; // changed line
}
As you can see, for 4-level nested calls, we changed ALL 4 functions, at the volume of at least 2 lines per function. YIKES. So for 10-level nested calls, adding 1 parameter changes all TEN functions and 20 lines.
Now, an example of the same change, except the arg list is now an object (or, for dynamic languages, a heterogeneous map would do :)
class args_class {
public:
int arg1, arg2, arg3, arg4, arg5;
}
}
args_class arg_object;
function f1(arg_object) {
res = f2(arg_object);
}
function f2(arg_object) {
res = f3(arg_object);
}
function f3(arg_object) {
res = f4(arg_object);
}
function f4(arg_object) {
return arg_object.arg1 + arg_object.arg4;
}
And what do we change to add arg6?
class args_class {
public:
int arg1, arg2, arg3, arg4, arg5, arg6; // line changed
}
}
// f1..f3 are unchanged
function f4(arg_object) {
return arg_object.arg1 + arg_object.arg4 + arg_object.arg6; // line changed
}
That's it. For 4-level nested methods, or for 10-level nested methods, you ONLY change 2 lines both.
Which one is less work to maintain?
I think it all depends on the context of the function parameters themselves. If you're relying on elements of some thing, then I'd pass a reference of that some thing as a parameter (whether it's a reference/pointer to an interface of that object or a reference/pointer to the object definition itself is an implementation detail).
If the parameter isn't derived directly from an object and there are a small number of parameters (five or less maybe? up to you really), then I'd pass atomic arguments.
If there are potentially a large number of arguments, then I'd create some sort of an init struct as a parameter, where the calling code instantiates and fills the struct and then passes a reference to it as an argument.
Suppose I write the following code:
public ref class Data
{
public:
Data()
{
}
Int32 Age;
Int32 year;
};
public void Test()
{
int age = 30;
Int32 year = 2010;
int* pAge = &age;
int* pYear = &year;
Data^ data = gcnew Data();
int* pDataYear = &data->Year; // pData is interior pointer and the compiler will throw error
}
If you compile the program, the compiler will throw error:
error C2440: 'initializing' : cannot convert from 'cli::interior_ptr' to 'int *'
So I learned the "&data->Year" is a type of interior pointer.
UPDATES: I tried to use "&(data->Year)", same error.
But how about pAge and pYear?
Are they native pointers, interior pointers or pinned pointers??
If I want to use them in the following native function:
void ChangeNumber(int* pNum);
Will it be safe to pass either pAge or pYear?
They (pAge and pYear) are native pointers, and passing them to a native function is safe. Stack variables (locals with automatic storage lifetime) are not subject to being rearranged by the garbage collector, so pinning is not necessary.
Copying managed data to the stack, then passing it to native functions, solves the gc-moving-managed-data-around problem in many cases (of course, don't use it in conjunction with callbacks that expect the original variable to be updated before your wrapper has a chance to copy the value back).
To get a native pointer to managed data, you have to use a pinning pointer. This can be slower than the method of copying the value to the stack, so use it for large values or when you really need the function to operate directly on the same variable (e.g. the variable is used in callbacks or multi-threading).
Something like:
pin_ptr<int> p = &mgd_obj.field;
See also the MSDN documentation