Xcode bibliothèque partagée .so

yachiro

Membre confirmé
22 Juin 2011
29
0
37
Bonjour à tous,

Je me présente, je suis un étudiant en master informatique actuellement en stage au sein d'une entreprise de sécurité informatique.

Dans le cadre de mon projet, j'ai été amené à créer une bibliothèque partagée sous linux (et également utilisable sur mac) dynamique de type .so.
Cette dernière se charge à partir d'un main qui fait appel aux fonctions dans cette dernière quand il en a besoin quand je l'exécute sur mon terminal.

Néanmoins, je dois à partir de maintenant passer dans l'univers MAC complètement flou pour moi encore et développer sous cocoa un programme qui puisse faire appel à cette même librairie à partir d'Xcode.

Dans un premier temps, il m'a été demandé de faire un tout petit programme sous Xcode en objective C qui fasse appel à une librairie partagée (.so ou .dylib je sais que la .so marchait bien quand je la chargeais sur mon terminal mais à partir d'Xcode je sais pas si ca va marcher à vous de me dire ! :D) toute simple contenant on va dire un simple printf "ca marche" histoire pour l'instant de vérifier que l'on fait bien appel à cette librairie.

À noter que cette librairie est codée en C et qu'elle devra rester telle quelle (c'est tout le but du projet) mais qu'on puisse faire appel aux fonctions de cette dernière à partir d'un programme sous Xcode.

Je sollicite donc votre aide car je suis un débutant en ce qui concerne le développement sous MAC OS et j'aimerais recueillir des idées ou des suggestions sur comment procéder !

Merci à tous de votre attention je vous souhaite une bonne fin de journée
 
A ton avis, y a-t-il une énorme diifférence entre compiler une appli ou une librairie sous Linux et sous Mac OSX ? :siffle: Non :rateau:

Pour l'utilisation de Xcode, il faudrait déjà commencer par lire un minimum le "fucking manual". Il y a quand même pas mal de choses décrites. :siffle:

Pour créer ta librairie, dans la liste des types de projet "Framework & Library", tu dois trouver ton bonheur : BSD C, STL C++ qui vont faire des .dylib (plutôt que des .so, mais c'est la même chose).
Mais il est plus "Mac" de faire un framework, la librairie dynamique c'est un peu "has been" sur Mac OSX. :D

Pour ajouter ta librairie à un projet d'application "Cocoa", clic droit sur le groupe "Frameworks" ou un de ses sous-groupes, puis pour une librairie dynamique "Add > Existing Files ..." et pour un framework "Add > Existing Framework ..."
 
Merci pour ta réponse j'suis d'accord que la shared lib c'est has been mais bon les ordres sont les ordres !

Donc j'ai créer manuellement ma .dylib sur le shell je l'ai testé rapidement elle marche correctement maintenant pour ce qui est de sur cocoa c'est une autre histoire.

Je l'ai ajouté aux frameworks comme tu me l'as suggéré

J'ai édité mon main pour qu'il fasse un dlopen de ma lib, et quand je compile voila ce que je reçois dans un premier temps :

Bloc de code:
ld: library not found for -l-m64
collect2: ld returned 1 exit status
Command /Developer/usr/bin/gcc-4.2 failed with exit code 1

Des idées sur où se trouve le soucis et comment y remédier?

Merci à tous
 
ld: library not found for -l-m64
Il faudrait qu'un jour, dans les cours d'informatique, on apprenne aux étudiants à lire les résultats de compil et de link :siffle: Comment peut-on programmer sans savoir comment marche l'outil de base, le compilateur ...

Qui est "m64" ? Ta lib "libm64.dylib" ? Où se trouve la librairie que tu as ajoutée ?
Il faut faire attention à ce genre de détail quand tu mets une appli en prod ...

Pour ajouter un chemin de recherche des librairies :
Clic droit sur la cible dans ton projet, "Get Info", onglet "Build", ligne "Library Search Paths"

Ca ajoute une directive -L à ta commande de compilation.

PS : le dlopen n'est utile que si tu charges dynamiquement des librairies en cours d'exécution, par exemple en fonction d'un type d'objet à traiter. Dans ton cas la librairie est déjà linkée à ton application. Tu peux accéder directement aux objets qui y sont définis.
 
PS : le dlopen n'est utile que si tu charges dynamiquement des librairies en cours d'exécution, par exemple en fonction d'un type d'objet à traiter. Dans ton cas la librairie est déjà linkée à ton application. Tu peux accéder directement aux objets qui y sont définis.

Merci pour ta réponse mais c'est la que se situe ma vraie question.
En fait jusqu'à présent un programme en C faisait appel à une librairie partagée DLL (windows comme tu l'auras deviné).

Pour des raisons évidentes d'utilité du logiciel, il fallait que ce dernier soit adapté aux autres OS.
J'ai donc d'abord adapter à linux (d'où la .so dont j'ai parlé qui fut créer à partir de la DLL en changeant ce qu'il fallait...etc) et en particulier le main qui DOIT charger dynamiquement la .so avec dlopen, dlsym ...Etc.
Sur linux après avoir un peu galéré, ca a fini par marcher.

Néanmoins, je dois maintenant adapter cela à Mac. L'idée est donc pour l'instant de faire un petit programme sur Xcode en objective C qui puisse faire appel à cette même librairie (elle écrite en C et devant rester telle quelle !).

Est il donc possible à partir d'un main obj-C d'appeler les fonctions d'une librairie C avec les outils dlopen, dlsym etc..? Si oui un mini mini exemple me serait d'une grande aide.
Si non quelles autres alternatives me reste t-il (je pense à celle de linker directement la lib à l'exec n'est ce pas?)

Merci pour vos réponses mais croyez bien que si je pose la question c'est que j'ai bien recherché avant sans trouver de réponses concluantes..
 
J'ai donc d'abord adapter à linux (d'où la .so dont j'ai parlé qui fut créer à partir de la DLL en changeant ce qu'il fallait...etc) et en particulier le main qui DOIT charger dynamiquement la .so avec dlopen, dlsym ...Etc.
Dans ce cas pas besoin d'ajouter la librairie au projet. Par contre il faut la mettre dans un répertoire défini dans DYLD_LIBRARY_PATH (ceci doit différer de Linux où se doit être LIBRARY_PATH)
 
Une dernière question après j'vous embête plus :D

J'ai réussi à charger correctement la dylib grâce à votre aide maintenant le résultat obtenu n'est pas celui que j'attendais.

Je m'explique avec un exemple simple où ma bibliothèque se contente de faire un simple
void ctest (int *var){
var = 100;
}
avec un programme C de base sous Linux et en utilisant les fonctions de chargement dynamique dlopen, dlsym, dlclose ..etc j'ai donc un programme main qui ressemble à ca
void ctest (int *);

int main(int argc, char **argv)
{
void *lib_handle;
double (*fn)(int *);
int x;
char *error;

lib_handle = dlopen("./libctest.so", RTLD_LAZY);
if (!lib_handle)
{
fprintf(stderr, "%s\n", dlerror());
exit(1);
}

fn = dlsym(lib_handle, "ctest1");
if ((error = dlerror()) != NULL)
{
fprintf(stderr, "%s\n", error);
exit(1);
}

(*fn)(&x);
printf("Valx=%d\n",x);

dlclose(lib_handle);
return 0;
}
Le print m'affiche que x = 100 tout se passe bien.

Maintenant comme je dois "implémenter ceci" sur Xcode en faisant un main équivalent capable de charger une librairie écrite en C.

Tout en gardant le même exemple que ce dernier (vu que les fonctions dlopen, dlsym etc.. sont équivalentes sous mac) je l'ai compilé sous Xcode avec cette fois ci un appel à une lib.dylib (qui fait la même chose que la .so) et le résultat vaut x = 0

Etant encore peu expérimenté sur Xcode et l'objective C en général, je voulais savoir si l'utilisation des pointeurs telle que je l'ai fais dans mon main.c ainsi que mes appels de fonction vont fonctionner de la même manière en objective C?

Si non, j'aimerais savoir à quoi ressemblerait ce main version Obj-C

Merci à tous pour votre aide je sais que j'en abuse !

Bonne journée