ffi / ffi-compiler

Apache License 2.0
32 stars 10 forks source link

How to create stub lib to call methods from C++ dynamic library? #13

Closed Envek closed 7 years ago

Envek commented 7 years ago

May be dumb question, as I haven't work with C since university, but I can't figure it out.

In https://github.com/ffi/ffi/issues/281 it's advised to use ffi-compiler to create a stub lib and binding that using FFI.

So, I have some custom.h file somewhere in my system (probably installed from some libcustom-dev package) and I have libcustom.so somewhere in my system (probably installed from some libcustom package).

In that custom.h contained next declaration:

int scaleImg( unsigned char *BufImg, int &Maxx, int &Maxy, int Dpi );

In corresponding libcustom.so it contained with C++ mangled name:

$ nm -gU libcustom.so | grep scaleImg
0000000000046410 T __Z8scaleImgPhRiS0_i

Question: how to use ffi-compiler in such a case to be able to call scaleImg from libcustom.so?

Will it be enough to do something like this in, say, example.cpp:

#include "example.h"
#include <custom.h>

RBFFI_EXPORT int rbScaleImg( unsigned char *BufImg, int &Maxx, int &Maxy, int Dpi );
{
  return scaleImg( BufImg, Maxx, Maxy, Dpi );
}

Thank you in advance.

Related issue: https://github.com/ffi/ffi/issues/554

stakach commented 7 years ago

http://www.tldp.org/HOWTO/C++-dlopen/thesolution.html

stakach commented 7 years ago

This would allow you to bind to the hello function using ruby ffi

#include <iostream>

extern "C" void hello() {
    std::cout << "hello" << '\n';
}
stakach commented 7 years ago

not really any other way - however you can probably use the mangled name if the library is pre-compiled. Each compiler mangles names in a different way

Envek commented 7 years ago

@stakach, thank you.

  1. I was able to successfully use mangled name (omitting first underscore:

    attach_function :scaleImg, '_Z8scaleImgPhRiS0_i', [:buffer_inout, IntPtr, IntPtr, :int], :int
  2. Specifying extern "C" before function declaration also helped. Previously I've tried to wrap whole custom.h file to the extern "C" { } block, but it broke everything (there were some linking errors at runtime).