delegates with C linkage

Zarathustra adam.chrapkowski at gmail.com
Sat Jun 5 11:43:52 PDT 2010


> but that will help on the caller side (you using gcc?) but D still won't
> accept an delegat in an extern C because this type does not exists in
> the C world
Maybe it is the reason but the error message is still nonsense.

> btw: can show us code where you do this and it works - why don't you use
> your working code as an example?
I haven't shown the code before for two reasons. The first one is that the my
project is big and the second one is that the possibility of doing that haven't
been a part of my question. If you want to know how to do that look at the examples.

(1)
Look at the following (probably most simple) example of d thiscall under c:
/*
 * test.c;
 */
#define d_foo_get_add _D4test3Foo6getAddMFiZi
#include <stdio.h>
typedef struct {
  void* vptr   ; /* unused */
  void* monitor; /* unused */

  int a;
} st_d_foo, *DFoo;

__attribute__((regparm(1), stdcall))
int d_foo_get_add(DFoo this, int o_addme) {
  return this->a += o_addme;
}
______________________________________________________________________________
/*
 * test.d
 */
module test;

static import std.stdio;

public class Foo {
  private int a;

  public int getAdd(int);
}

void main() {
  Foo foo = new Foo();
  foo.a = 5;
  std.stdio.writefln("foo.a = %d", foo.getAdd(4));
}
______________________________________________________________________________
/* command line: */
gcc test.c -c -otest.c.o
dmd test.d -c -oftest.d.o
dmd test.d.o test.c.o -oftest
______________________________________________________________________________
/* output is of course*/
foo.a = 9
______________________________________________________________________________
(2)
And now lets add delegate:

/*
 * test.c;
 */
#define d_foo_get_var _D4test3Foo6getAddMFiZi
#define d_foo_dlg     _D4test3Foo3dlgMFDFZiZv

#define call_delegate(x) (x).funcptr((x).ptr)

#include <stdio.h>
typedef struct {
  void* vptr   ; /* unused */
  void* monitor; /* unused */

  int a;
} st_d_foo, *DFoo;

typedef struct {
  void* ptr;
  int (__attribute__((regparm(1), stdcall)) * funcptr)(void*);
} st_d_delegate;

__attribute__((regparm(1), stdcall))
int d_foo_get_var(DFoo this, int o_addme) {
  return this->a += o_addme;
}

__attribute__((regparm(1), stdcall))
void d_foo_dlg(DFoo this, st_d_delegate o_handler) {
  printf("dlg = %d\n", call_delegate(o_handler));
}
______________________________________________________________________________
/*
 * test.d
 */
module test;

static import std.stdio;

public class Foo {
  private int a;

  public int getAdd(int);
  public void dlg(int delegate());
}

public class Bar {
  int get7() { return 7; }
}

void main() {
  Foo foo = new Foo();
  foo.a = 5;
  std.stdio.writefln("foo.a = %d", foo.getAdd(4));

  Bar bar = new Bar();
  foo.dlg(&bar.get7);
}
______________________________________________________________________________
command line is the same
______________________________________________________________________________
/* output */
foo.a = 9
dlg = 7


More information about the Digitalmars-d-learn mailing list