es.davy.ai

Preguntas y respuestas de programación confiables

¿Tienes una pregunta?

Si tienes alguna pregunta, puedes hacerla a continuación o ingresar lo que estás buscando.

Utilizando biblioteca compartida de C++ en Idris.

Quiero utilizar FFI para acceder a una biblioteca de C++ de terceros desde Idris, pero recibo “símbolo indefinido”. Soy nuevo en la compilación de C/C++.

Estoy haciendo esto envolviendo el código C++ en una capa pura de C que llamo desde Idris. El código C++ se proporciona como un conjunto de encabezados .h y una sola biblioteca compartida .so. Actualmente solo tengo un archivo C, pero puede que tenga más más adelante.

Aquí está el encabezado de la biblioteca C++ include/foo.h:

“`c++
#include <some other/library/header.h="">

namespace mynamespace {
class Foo {
public:
Foo();
}
}

<pre><code><br />Y el envoltorio C wrapper.cpp:

“`c
#include <foo.h>

extern “C” {
struct cFoo;

using namespace mynamespace;

struct cFoo* cFoo_new() {
return reinterpret_cast<cfoo*>(new Foo());
}
}

La biblioteca compartida es lib/libfoo_ext.so y estoy compilando esto con:

g++ -shared -Iinclude -Llib -lfoo_ext -o libfoo.so wrapper.cpp

Eso funciona sin errores. Mientras tanto, el código de Idris es:

module Foo

import System.FFI

export
Foo : Type
Foo = Struct "cFoo" []

%foreign "C:cFoo_new,libfoo"
export
mkFoo : Foo

Estoy llamando a mkFoo en un archivo de prueba. Cuando lo hago, obtengo:

Exception: (while loading libfoo.so) .../build/exec/tmpchez_app/libfoo.so: undefined symbol: _ZN17mynamespace6FooC1Ev</cfoo*></foo.h>

Tags:  , , , ,

Answer

  1. Avatar for davy.ai

    El mensaje de error “símbolo no definido” indica que el vinculador no puede encontrar la definición para el constructor mynamespace::Foo(). Esto es probablemente porque el código C++ no está siendo vinculado correctamente con el código C.

    Una posible solución es asegurarse de que el código C++ se compile con la bandera de posición-independiente (-fPIC) para que pueda ser vinculado correctamente con el código C:

    g++ -shared -Iinclude -Llib -lfoo_ext -fPIC -o libfoo.so wrapper.cpp
    

    Además, puede ser necesario incluir la biblioteca estándar de C++ al vincular:

    g++ -shared -Iinclude -Llib -lfoo_ext -fPIC -lstdc++ -o libfoo.so wrapper.cpp
    

    Si esto no resuelve el problema, puede ser útil verificar que la biblioteca libfoo_ext.so también se compila con -fPIC y que se incluyen los encabezados apropiados en wrapper.cpp.

    Una vez que el código esté vinculado correctamente, la función mkFoo debería poder crear una instancia de mynamespace::Foo desde Idris.

Comments are closed.