2009-04-02 6 views
2

J'ai une bibliothèque shim (partagée, C++) qui appelle les fonctions dans une autre bibliothèque partagée (libexif) et présente une interface simple avec C# pour les appels Platform Invoke. (Par exemple, un programme C# utilise PInvoke pour appeler ma bibliothèque partagée personnalisée qui à son tour appelle une autre bibliothèque partagée.)Linux, Mono, bibliothèques partagées et symboles non résolus

Sous Windows, ma bibliothèque partagée personnalisée est liée à la bibliothèque partagée lorsque mes liens de bibliothèque personnalisée et l'application C# s'exécute, tous les symboles sont résolus.

Sous Linux, l'association de ma bibliothèque partagée ne lie pas l'autre bibliothèque partagée. Avec un pilote C++, je spécifie l'autre bibliothèque lorsque l'application est liée et à ce moment-là, tous les symboles sont résolus. Toutefois, lorsque j'essaie d'appeler ma bibliothèque partagée à partir d'un programme C# (compilé en utilisant le mode mono), les symboles de l'autre bibliothèque partagée ne sont pas résolus. J'ai essayé d'utiliser la variable MONO_PATH pour spécifier l'autre bibliothèque mais cela ne semble pas faire de différence. J'ai également essayé de spécifier la fonction non résolue dans une instruction DLLimport, mais cela ne semble pas aider non plus.

Comment puis-je spécifier une bibliothèque partagée qui n'est pas directement appelée par le code C# afin que mono/cli la trouve au moment de l'exécution?

J'utilise les commandes suivantes pour construire la bibliothèque partagée:

g++ -fPIC -g -c -Wall libexif-wrapper.cpp 
g++ -shared -Wl,-soname,libexif-wrapper.so.1  -o libexif-wrapper.so.1.0.1 libexif-wrapper.o -lc 
ar rcs libexif-wrapper.a libexif-wrapper.so.1 

Et la ligne de commande suivante pour compiler mon pilote C#:

mcs -unsafe -define:LINUX Test-libexif-wrapper.cs 

Lors de l'exécution, je reçois une erreur qu'un symbole utilisé par ma bibliothèque partagée est introuvable:

/usr/bin/cli: symbol lookup error: ../../../C/libexif-wrapper/libexif-wrapper/libexif-wrapper.so.1: undefined symbol: exif_data_new_from_file 

(libexif-wrapper est ma bibliothèque partagée wh ich sert de cale entre l'application C# et libexif.)

Je n'ai pas réussi à trouver de solution à ce problème. Toute suggestion serait appréciée.

modifier: Pour répondre à la question:

Are you sure that the unmanaged libexif-wrapper can be found in the LD_LIBRARY_PATH environment variable?

En fait, ce n'est pas. J'ai créé le chemin dans le DLLImport pour pointer directement à la place. L'heure d'exécution le trouve car il indique le chemin d'accès dans le message d'erreur ci-dessus. De plus le symbole manquant n'est pas appelé par le programme C# mais plutôt l'une des fonctions dans ma bibliothèque partagée appelle la fonction qui est alors introuvable. (Merci - hank)

Répondre

2

Vous devez spécifier la dépendance lorsque vous liez la bibliothèque wrapper comme

g++ -shared -Wl,-soname,libexif-wrapper.so.1 -o libexif-wrapper.so.1.0.1 libexif-wrapper.o -lc -lexif 

Quand vous faites cela l'éditeur de liens dynamique sait que libexif-emballage dépend libexif et il peut résoudre les symboles sur la charge.

+0

J'ai testé votre solution complètement aujourd'hui en utilisant Code :: Blocks 16.11 et j'obtiens toujours l'erreur d'exécution/usr/bin/mono: erreur de recherche de symbole: /home/venkat/DevelopmentX64/SmartCamXi_Hybrid_Linux/Debug/libDataServerLib64.so: symbole non défini: _Z15ciIPC_OpenMutexPKc – Frank

2

Je suis confus au sujet de la raison pour laquelle vous avez besoin -lc, mais peut-être est une bizarrerie Mono ...

Est-ce que ça marche si vous ajoutez -lexif à la commande de lien? Il semble que vous créez une bibliothèque partagée avec des symboles indéfinis, mais ne dites pas ces symboles devraient provenir. C'est parfois utile parfois - par exemple, créer un plugin qui utilise un symbole qui devrait être déjà fourni par l'application qui le charge - mais pas ce que vous voulez ici; Je ne vois pas comment libdl (ou cependant les bibliothèques de chargement Mono, peut-être qu'il a sa propre implémentation) sauraient qu'il doit charger libexif.so pour une utilisation dans votre bibliothèque.

J'espère que vous n'avez pas à faire quelque chose d'horrible comme ajouter libexif.so à l'archive ...

+0

Oui, merci à tous les deux. Ajouter -lexif à la commande de liaison pour ma bibliothèque de shim résout le problème. Il indique que -lc n'est pas nécessaire. Cela faisait partie d'un exemple que j'ai copié (et je l'ai copié de façon servile). L'éliminer semble ne causer aucune difficulté à mon application de test C++ ni à mon application de test C#. – HankB

Questions connexes