question-mark
Stuck on an issue?

Lightrun Answers was designed to reduce the constant googling that comes with debugging 3rd party libraries. It collects links to all the places you might be looking at while hunting down a tough bug.

And, if you’re still stuck at the end, we’re happy to hop on a call to see how we can help out.

Function pointers

See original GitHub issue

I am trying to pass function pointers as struct members to a c api using ffi. Here is the function definitions and the struct in c

struct Session {
    PWLOG *pwLog;
    PWACCEPT *pwAccept;
    PWSEND *pwSend;
};

void * create_session(struct Session *session);

typedef int PWLOG(const char *type, const char *msg);

typedef const char * PWACCEPT(const char *keys, const char *replyStr, size_t replyStrSize);

typedef void PWSEND(const char *type, const char *msg);

Here is the struct defined in javascript using ref-struct with ffi.

const pwLogFunc = function(type, message) {

    console.log(type.readCString(), message.readCString());
};

const pwSendFunc = function (type, msg) {

   console.log(type.readCString(), msg.readCString());
};

const pwAcceptFunc= function (keys, replyStr, replyStrSize) {

   console.log(keys.readCString(), replyStr.readCString(), replyStrSize);
}


const Session = Struct({
    pwLog:  pwLogFunc,
    pwSend: pwSendFunc,
    pwAccept: pwAcceptFunc
});

const structPtr = Ref.refType(Session);    

const lib = Ffi.Library(dllPath, { 
    'create_session': ['void *', [structPtr]]
});

const session = new Session({
    pwLog: pwLogFunc,
    pwAccept: pwAcceptFunc,
    pwSend: pwSendFunc
});

const result = lib.create_session(session.ref());

Any help would be greatly appreciated as my knowledge of c is very limited!

Issue Analytics

  • State:open
  • Created 7 years ago
  • Comments:7 (3 by maintainers)

github_iconTop GitHub Comments

2reactions
asm-jaimecommented, Apr 23, 2018

Perhaps the topic is already outdated, but here’s a example, how to call a function pointer inside a c-struct: data.h:

typedef struct data {
  int some;       // some variable
  void (*exec)(); // pointer to a function
} data;

void exec_data(data *v);

data.c:

#include "data.h"

void exec_data(data *v) {
  v->some = v->some >> 2;
}

wrapper.c, here we can allocate/free memory for the structs:

#include <stdint.h>
#include <stdlib.h>

#include "data.h"

#if defined(WIN32) || defined(_WIN32)
#define EXPORT __declspec(dllexport)
#else
#define EXPORT
#endif

EXPORT data *init_data(void){
  data *p_data = (data *)malloc(1*sizeof(data));
  p_data->some = 0;
  p_data->exec = exec_data;
  return p_data;
}

EXPORT void free_data(void *v){
  free(v);
}

after gcc -shared -fpic data.c wrapper.c -o data.so we can use it in data.js:

'use strict'

const ffi = require('ffi');
const ref = require('ref');
const struct = require('ref-struct');

const data = struct({
  'some': 'int',
});
data.defineProperty('exec', ffi.Function('void', [ref.refType(data)]));

const dataPtr = ref.refType(data);

const lib = ffi.Library('./data', {
  'init_data': [ dataPtr, [ ] ],
  'free_data': ['void', ['void *']]
})

const r_data = lib.init_data().deref();

r_data.some = 100;
console.log(`data.some: ${r_data.some}`);
r_data.exec(r_data.ref());  // <== call function pointer
console.log(`data.some: ${r_data.some}`);

lib.free_data(r_data.ref());

result:

data.some: 100
data.some: 25

I hope this example will be useful.

1reaction
TooTallNatecommented, Sep 26, 2016

If your pwCreate() function really does return the Session *, then you probably want to iteratively define the struct fields, so that you can access Session:

const Session = Struct();
Session.defineProperty('pwLog', ffi.Function(ref.refType(Session), ['string', 'string']),
...
Read more comments on GitHub >

github_iconTop Results From Across the Web

Function Pointer in C - GeeksforGeeks
1) Unlike normal pointers, a function pointer points to code, not data. Typically a function pointer stores the start of executable code.
Read more >
Function Pointers in C and C++ - Cprogramming.com
A function pointer is a variable that stores the address of a function that can later be called through that function pointer.
Read more >
Function pointer - Wikipedia
A function pointer, also called a subroutine pointer or procedure pointer, is a pointer that points to a function. As opposed to referencing...
Read more >
How do function pointers in C work? - Stack Overflow
A function pointer is a variable that contains the address of a function. Since it is a pointer variable though with ...
Read more >
Pointers to functions - IBM
A pointer to a function points to the address of the executable code of the function. You can use pointers to call functions...
Read more >

github_iconTop Related Medium Post

No results found

github_iconTop Related StackOverflow Question

No results found

github_iconTroubleshoot Live Code

Lightrun enables developers to add logs, metrics and snapshots to live code - no restarts or redeploys required.
Start Free

github_iconTop Related Reddit Thread

No results found

github_iconTop Related Hackernoon Post

No results found

github_iconTop Related Tweet

No results found

github_iconTop Related Dev.to Post

No results found

github_iconTop Related Hashnode Post

No results found