IdentifiantMot de passe
Loading...
Mot de passe oublié ?Je m'inscris ! (gratuit)
Navigation

Inscrivez-vous gratuitement
pour pouvoir participer, suivre les réponses en temps réel, voter pour les messages, poser vos propres questions et recevoir la newsletter

PostgreSQL Discussion :

Création de fonction en C


Sujet :

PostgreSQL

  1. #1
    Membre à l'essai
    Profil pro
    Inscrit en
    Avril 2008
    Messages
    11
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Avril 2008
    Messages : 11
    Points : 10
    Points
    10
    Par défaut Création de fonction en C
    Bonjour,

    Je tente désespérement de créer une librairie dynamique pour étendre PostgreSQL.
    Mon niveau de C n'est plus ce qu'il était, mais ce n'est pas un problème. Mon plus gros soucis vient de la compilation.

    En me baladant sur ce forum, j'ai pu lire des post de développeurs à propos de ces librairies, mais ils arrivent à compiler, eux en sont déjà à l'étape suivante...

    Je précise que je suis sous Windows XP.
    Le tutorial officiel n'en parle pas et c'est dommage.

    Alors, j'ai installé MinGW, et j'ai suivi le tuto de Postgresql: http://www.postgresql.org/docs/8.3/i...e/xfunc-c.html

    Mais ma compilation connaît des échecs:

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    gcc -I"C:\Program Files\PostgreSQL\8.3\include\server" -I"c:\Program Files\PostgreSQL\8.3\include\server\port\win32" -o test.o -c test.c

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    In file included from C:/Program Files/PostgreSQL/8.3/include/server/postgres.h:48,
                     from test.c:10:
    C:/Program Files/PostgreSQL/8.3/include/server/c.h:97:21: libintl.h: No such file or directory
    test.c: In function `makepoint':
    test.c:49: error: `Point' undeclared (first use in this function)
    test.c:49: error: (Each undeclared identifier is reported only once
    test.c:49: error: for each function it appears in.)
    test.c:49: error: `pointx' undeclared (first use in this function)
    test.c:50: error: `pointy' undeclared (first use in this function)
    test.c:51: error: `new_point' undeclared (first use in this function)
    test.c:51: error: syntax error before ')' token
    Je vois donc qu'il manque un header.

    Le problème est sûrement minuscule pour quelqu'un qui s'y connait, j'en suis conscient. C'est d'autant plus frustrant.

    Sans céder au pessimisme, j'ai déjà eu, sur d'autres projets, des problèmes de fichiers manquants qui m'ont fait voyager dans forum en forum, de site en site, pour toujours finalement me retrouver avec un fichier manquant, ou d'autres problèmes à régler, et ça n'en finissait jamais.

    C'est pour cela que je préfère demander cash quelle est la bonne marche à suivre pour développer une extension C à PostgreSQL sous Windows...

    Merci d'avance

  2. #2
    Membre régulier
    Inscrit en
    Avril 2008
    Messages
    89
    Détails du profil
    Informations forums :
    Inscription : Avril 2008
    Messages : 89
    Points : 83
    Points
    83
    Par défaut C-Fonction pour Windows toujours pas dans la doc !
    Bonjour,

    je t'envoies le message que j'ai déjà posté à quelques uns.
    Ils s'en sont sorti avec ce fouilli.
    Si tu as des soucis je repasse de temps en temps sur ces pages.

    ------

    comme je n'ai pas beaucoup de temps devant moi et que je ne suis plus sur ce problème depuis quelques temps, j'aurai voulu t'envoyer des docs au format pdf et word -en particulier une doc très succinte que j'ai rédigé et qui montre comment développé des fonctions c (dll) pour postgreSQL avec DevCpp (libre basé sur gcc donc tranquile)... Hélas, je ne sais pas comment faire sur ce forum pour t'envoyer une pièce jointe. Tu peux me donner ton adresse mail et je te ferai parvenir tout cela sans soucis. Pour le code, si les docs ne suffisent pas, il faudra que je regarde si j'ai des exemples qui ne soient pas trop confidentiels.

    En attendant, je peux te donner quelques liens qui devrait te permettre de t'en sortir...

    Pour la base (docs officielles - no Bill) :
    • la bonne documentation de Joe Conway sur www.joeconway.com/tut_oscon_2004.pdf
    • la documentation PostGre sur http://www.postgresql.org/docs/8.3/i...ive/index.html

    Pour ce qui est du problème de link (sous Bill) de la dll dû à la macro BUILDING_DLL et au PG_MODULE_MAGIC :
    http://www.mydatabasesupport.com/for...oc-broken.html

    Et enfin la perle tchèque (pour la manipulation des tables, etc...) :
    http://www.pgsql.cz/index.php/Projec...for_PostgreSQL

    Avec ces deux derniers liens tu devrais pouvoir t'amuser....

    Bon allez je te fais un copier/coller d'une petite doc que j'avais rédigée et que je viens de retrouver :

    Citation:
    Programmation de fonction C sous PostGre SQL


    Ce document explique comment créer des modules en C pour PostGre SQL.

    L’intérêt est multiple et permet entre autre de :
    • protéger son code car il est encapsulé en binaire dans une DLL
    • améliorer les performances en temps de calcul
    • faire appel à des bibliothèques C, par exemple pour effectuer des opérations géométriques ou autres sur les objets manipulés

    La limite principale est la perte du caractère relationnel lors de l’utilisation des objets au sein du module C...

    L’idée est donc d’utiliser les fonctions C pour les opérations de calcul uniquement.

    Le principe général est de développer une DLL en C contenant différents éléments fonctionnels puis de créer pour chacun de ces éléments fonctionnels une fonction PostGre qui l’appelle.

    Création de la DLL avec DevCpp
    Nous utiliserons DevCpp (interface de développement Win32 gratuite basée sur le compilateur gcc).

    Pour créer la DLL :
    • Fichier  nouveau  projet
    • Choisir DLL et C puis enter le nom de la DLL (ma_dll)
    • Clic droit sur l’onglet dllmain.h  supprimer
    • Sauvegarder maindll.c

    Option du compilateur :
    • Aller dans Projets  options du projet
    • Dans l’onglet Paramètres enlever la commande -DBUILDING_DLL=1
    • Dans l’onglet Paramètres ajouter le fichier PostGre/lib/libpostgre.a
    • Dans l’onglet Repertoire  Repertoire d’include ajouter les 2 répertoires suivant :
    o Postgre/include/server
    o Postgre/include/server/port/win32

    A ce stade, sauvegarder.
    Il nous faut maintenant écrire notre programme dans dllmain.c

    Adaptation nécessaire sous plateforme Win32

    Nous avons supprimé l’option de génération de la macro BUILDING_DLL car celle-ci rentre en conflit avec la macro du même nom des headers (.h) de PostGre, ce qui définit les variables de PostGre en export alors que l’on cherche justement à les importer dans notre code. C’est uniquement les éléments fonctionnels de notre DLL qui doivent être définit en export. Ainsi on utilisera la macro PGMODULEEXPORT pour déclarer les éléments fonctionnels que l’on souhaite exporter vers PostGre (ou une autre application). Tout ceci est spécifique aux plateformes Win32 et demande quelques adaptations. Ainsi placer le code suivant au début du fichier dllmain.c (sont mis aussi les fichiers principaux à inclure) :


    Code C : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    58
    59
    60
    61
    62
    63
    64
    65
    66
    67
    68
    /********* ADAPTATION PLATEFORME WIN 32 ***************/
     
    #if defined(_MSC_VER) || defined(__MINGW32__)
    #ifndef _USE_32BIT_TIME_T
    #define _USE_32BIT_TIME_T
    #endif
    #endif
     
    #ifdef BUILDING_DLL
    #error Do not define BUILDING_DLL when building extension libraries
    #endif
     
    #ifndef BUILDING_MODULE
    #define BUILDING_MODULE
    #endif
     
    #include "postgres.h"
    #include <string.h>
    #include "fmgr.h"
    #include "utils/geo_decls.h"
    #include "executor/executor.h"
    #include "funcapi.h"
    #include "executor/spi.h"
    #include "utils/array.h"
    #include "utils/lsyscache.h"
    #include "miscadmin.h"
    #include <windows.h>
    #include <stdio.h>
    #include <stdlib.h>
     
    #undef PG_MODULE_MAGIC
    #undef PG_FUNCTION_INFO_V1
     
    #if defined(_MSC_VER) || defined(__MINGW32__)
    #if defined(BUILDING_MODULE)
    #define PGMODULEEXPORT __declspec (dllexport)
    #else
    #define PGMODULEEXPORT __declspec (dllimport)
    #endif
    #else
    #define PGMODULEEXPORT
    #endif
     
    #define PG_MODULE_MAGIC \
    PGMODULEEXPORT Pg_magic_struct * \
    PG_MAGIC_FUNCTION_NAME(void) \
    { \
    static const Pg_magic_struct Pg_magic_data = PG_MODULE_MAGIC_DATA; \
    return &Pg_magic_data; \
    } \
    extern int no_such_variable
     
    #define PG_FUNCTION_INFO_V1(funcname) \
    PGMODULEEXPORT const Pg_finfo_record * \
    CppConcat(pg_finfo_,funcname) (void) \
    { \
    static const Pg_finfo_record my_finfo = { 1 }; \
    return &my_finfo; \
    } \
    extern int no_such_variable
     
    PG_MODULE_MAGIC;
     
    #ifndef SET_VARSIZE
    #define SET_VARSIZE(n,s) VARATT_SIZEP(n) = s; 
    #endif
     
    /***********************************************************/

    A ce stade supprimer les fichiers d’include initiaux qui étaient présent dans le fichier dllmain.c (ils sont dans le code précédent) ainsi que la définition de la fonction HelloWorld initiale. Il ne reste donc que le code précédent et la définition de DllMain. Compiler.
    Un warning est levé. C’est normal.
    Voir http://www.mydatabasesupport.com/for...oc-broken.html pour un complément d’information.
    Premier élément fonctionnel : gestion des scalaires

    Tous les éléments fonctionnels de la DLL doivent être écrit entre le code d’adaptation pour Win32 et la définition de DllMain. La syntaxe pour les éléments devant être exporter et toujours la même :

    PG_FUNCTION_INFO_V1(mon_element_fonctionnel);

    PGMODULEEXPORT Datum mon_element_fonctionnel(PG_FUNCTION_ARGS)
    { …… code ……… }

    PG_FUNCTION_INFO_V1 est la macro qui indique que l’on utilise la convention 1 de développement (la seule possible sous Win32). PGMODULEEXPORT indique que l’on souhaite exporter cet élément. ‘mon_element_fonctionnel’ est le nom de notre élément dans la DLL, on pourra lui donner un nom différent sous PostGre. Enfin, PG_FUNCTION_ARGS est une macro générale non utilisée directement et Datum est le ‘supertype’ des objets PostGre en C. Presque tout objet peut être convertit en Datum.

    Pour récupérer la valeur d’un paramètre on utilise PG_GETARG_XXX(0) pour le premier, PG_GETARG_XXX(1) pour le suivant, etc….
    Pour retourner une valeur on utilise PG_RETURN_XXX(valeur_de_retour).
    XXX définit le type d’objet manipulé.
    Ainsi le code suivant définit un élément fonctionnel qui prend un paramètre de type entier (integer sous PostGre et int32 en C) et renvoie ce paramètre incrémenté de un :

    PG_FUNCTION_INFO_V1(add_one);

    PGMODULEEXPORT Datum add_one(PG_FUNCTION_ARGS)
    {
    int32 arg = PG_GETARG_INT32(0);

    PG_RETURN_INT32(arg + 1);
    }

    D’autres exemples sont donnés dans la documentation de PostGre indiquant comment gérer les types double précision et texte.

    A ce stade la compilation doit donner le même résultat que précédemment. On obtient alors dans le répertoire de notre projet un fichier dll. La DLL est prête à être importée sous PostGre.
    Première fonction C PostGre : gestion des scalaires

    Copier le fichier dll réalisé et le coller dans un emplacement spécifique accessible depuis le serveur PostGre : par exemple dans ‘mon_repertoire_dll’.

    Editer alors la requête suivante :

    CREATE FUNCTION ma_dll_elem_add_one(integer)
    RETURNS integer
    AS 'mon_repertoire_dll/ma_dll', 'add_one'
    LANGUAGE C STRICT;

    A ce stade la fonction C de PostGre ‘ma_dll_elem_add_one’ est créée et appellera l’élément fonctionnel ‘add_one’ de la DLL ‘ma_dll’ présente dans le répertoire ‘mon_repertoire_dll’.

    Select ma_dll_elem_add_one(15) devrait renvoyer la valeur 16.

    Voilà le principe général de création de fonctions C sous Postgre.

    Pour aller plus loin …
    Voilà, si tout c’est bien déroulé, le problème principal qui est l’adaptation du code pour la plateforme Win32 est réglé et il serait vain de reprendre tout ce qui est indiqué dans les différentes documentations disponibles. Il ne reste plus qu’à tester par la pratique. On trouvera des exemples dans
    • la bonne documentation de Joe Conway sur www.joeconway.com/tut_oscon_2004.pdf
    • la documentation PostGre sur http://www.postgresql.org/docs/8.3/i...ive/index.html


    Par FBM en Juillet 2008.
    Bonne chance ... Avec tout cela je m'en suis sorti et j'ai réussi à faire tout ce que je voulais : manipulation de scalaire, de tables, etc...

    Si tu avances bien sur le sujet n'hésite pas à me mailer une petite doc ou des liens etc... en particulier je n'ai pas trop cherché à utiliser directement les données spatiales de postgis avec des fonctions C (je transforme toujours en x,y ou autres) et je ne sais pas si cela est possible. Si tu avances là dessus n'hésites pas... De même si tu ne t'en sors pas avec ce fouilli d'information n'hésites pas non plus.

    Bonne journée.

  3. #3
    Membre régulier
    Inscrit en
    Avril 2008
    Messages
    89
    Détails du profil
    Informations forums :
    Inscription : Avril 2008
    Messages : 89
    Points : 83
    Points
    83
    Par défaut LIBPQ ou C-Function ?
    Re-bonjour,

    à vous relire, et malgré le lien, j'ai un doute : voulez-vous développer des fonctions C pour postgre (que l'on appelle depuis PG) ou voulez-lous utiliser la libpq pour accéder au serveur depuis un programme C ?

    Ce que je vous ai donné concerne la création de fonctions C mais j'ai aussi quelques infos pour la compilation de la libpq sous Windows qui pose aussi parfois quelques problèmes.

    Bonne chance et n'hésitez pas à poster les problèmes rencontrés.

  4. #4
    Membre à l'essai
    Profil pro
    Inscrit en
    Avril 2008
    Messages
    11
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Avril 2008
    Messages : 11
    Points : 10
    Points
    10
    Par défaut
    navré pour cette réponse tardive. je n'avais pas la notification.
    Je vais étudier toutes ces informations.
    Effectivement, je souhaite avec des fonctions C pour enrichir le serveur PostgreSQL, et non utiliser libpq.

    Merci beaucoup pour votre contribution, en tout cas

  5. #5
    Candidat au Club
    Profil pro
    Inscrit en
    Juillet 2010
    Messages
    2
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Juillet 2010
    Messages : 2
    Points : 2
    Points
    2
    Par défaut
    Je ressors ce post des profondeurs pour dire un grand merci à VASAPANCH !! J'ai enfin réussi à faire quelque chose grâce à ton tuto.

    Je rajoute cependant qu'avec la version PostgreSQL 8.4 on ne peut pas
    "Dans l’onglet Paramètres ajouter le fichier PostGre/lib/libpostgre.a"
    puisque ce fichier n'existe plus.
    Mais ce n'est pas grave ça fonctionne quand même, mais au lieu de faire
    "Dans l’onglet Repertoire  Repertoire d’include ajouter les 2 répertoires suivant :
    o Postgre/include/server
    o Postgre/include/server/port/win32
    "

    J'ai fait :
    Dans la fenêtre principale de dev-c++, cliquer sur l'onglet "Outils", puis "Option du compilateur". Votre fenêtre d'option s'ouvre. Choisir l'onglet "Répertoires" et dans celui-ci "Repertoires C .h".
    Ajouter alors :
    • PostgreSQL\8.4\include
    • PostgreSQL\8.4\include\server
    • PostgreSQL\8.4\include\server\win32


    Et voilà tout fonctionne à merveille !

+ Répondre à la discussion
Cette discussion est résolue.

Discussions similaires

  1. Création de fonctions dans DLL
    Par salrouge dans le forum VB 6 et antérieur
    Réponses: 5
    Dernier message: 23/08/2006, 10h42
  2. Création de fonction ou méthode
    Par sam.fet dans le forum ASP
    Réponses: 2
    Dernier message: 03/08/2006, 17h17
  3. Création de fonction
    Par Lo² dans le forum MS SQL Server
    Réponses: 5
    Dernier message: 13/07/2006, 12h00
  4. Création de fonction
    Par benazerty dans le forum Access
    Réponses: 6
    Dernier message: 14/04/2006, 11h40
  5. Réponses: 5
    Dernier message: 30/03/2006, 15h52

Partager

Partager
  • Envoyer la discussion sur Viadeo
  • Envoyer la discussion sur Twitter
  • Envoyer la discussion sur Google
  • Envoyer la discussion sur Facebook
  • Envoyer la discussion sur Digg
  • Envoyer la discussion sur Delicious
  • Envoyer la discussion sur MySpace
  • Envoyer la discussion sur Yahoo