J'écris un programme dans le D qui utilise svn et je suis tombé sur quelque chose que je n'arrive pas à comprendre comment convertir en syntaxe D. J'ai pris un coup de couteau, mais ça se grave.Ajouter tableau en utilisant apr_array_push dans D
Exemple de ce que je suis en train d'accomplir en C:
svn_auth_provider_object_t provider;
providers = apr_array_make(pool, 1, sizeof(svn_auth_provider_object_t*));
svn_auth_get_simple_provider2(&provider, null, null, pool);
*(svn_auth_provider_object_t**)apr_array_push (providers) = provider;
svn_auth_open(&auth_baton, providers, pool);
Pour autant que je sache, ce code fonctionne très bien. J'ai trouvé plusieurs exemples faits presque exactement de la même manière. Voici ma tentative de copier ceci dans D:
svn_auth_provider_object_t provider;
providers = apr_array_make(pool, 1, svn_auth_provider_object_t.sizeof);
svn_auth_get_simple_provider2(&provider, null, null, pool);
void* newSlot = apr_array_push(m);
newSlot = provider;
svn_auth_open(&auth_baton, providers, pool);
Cela jette une erreur de segmentation sur svn_auth_open. Ma meilleure estimation est que le contenu du fournisseur ne se termine pas au pointeur détenu par newSlot. Et je ne suis pas sûr de savoir pourquoi.
Code supplémentaire:
/// Code taken from Apache's APR libary which is licensed under Apache License, Version 2.0
struct apr_array_header_t {
apr_pool_t* pool;
int elt_size;
int nelts;
int nalloc;
char* elts;
};
struct svn_auth_provider_object_t
{
svn_auth_provider_t *vtable;
void *provider_baton;
}
APR_DECLARE(void *) apr_array_push(apr_array_header_t *arr)
{
if (arr->nelts == arr->nalloc) {
int new_size = (arr->nalloc <= 0) ? 1 : arr->nalloc * 2;
char *new_data;
new_data = apr_palloc(arr->pool, arr->elt_size * new_size);
memcpy(new_data, arr->elts, arr->nalloc * arr->elt_size);
memset(new_data + arr->nalloc * arr->elt_size, 0,
arr->elt_size * (new_size - arr->nalloc));
arr->elts = new_data;
arr->nalloc = new_size;
}
++arr->nelts;
return arr->elts + (arr->elt_size * (arr->nelts - 1));
}
#define APR_ARRAY_IDX(ary,i,type) (((type *)(ary)->elts)[i])
#define APR_ARRAY_PUSH(ary,type) (*((type *)apr_array_push(ary)))
void
svn_auth_open(svn_auth_baton_t **auth_baton,
apr_array_header_t *providers,
apr_pool_t *pool)
{
svn_auth_baton_t *ab;
svn_auth_provider_object_t *provider;
int i;
/* Build the auth_baton. */
ab = apr_pcalloc(pool, sizeof(*ab));
ab->tables = apr_hash_make(pool);
ab->parameters = apr_hash_make(pool);
ab->creds_cache = apr_hash_make(pool);
ab->pool = pool;
/* Register each provider in order. Providers of different
credentials will be automatically sorted into different tables by
register_provider(). */
for (i = 0; i < providers->nelts; i++)
{
provider_set_t *table;
provider = APR_ARRAY_IDX(providers, i, svn_auth_provider_object_t *);
/* Add it to the appropriate table in the auth_baton */
table = apr_hash_get(ab->tables,
provider->vtable->cred_kind, APR_HASH_KEY_STRING);
if (! table)
{
table = apr_pcalloc(pool, sizeof(*table));
table->providers
= apr_array_make(pool, 1, sizeof(svn_auth_provider_object_t *));
apr_hash_set(ab->tables,
provider->vtable->cred_kind, APR_HASH_KEY_STRING,
table);
}
APR_ARRAY_PUSH(table->providers, svn_auth_provider_object_t *)
= provider;
}
*auth_baton = ab;
}
Ma meilleure estimation est que le segfault se passe dans APR_ARRAY_IDX. Tout le reste a une adresse mémoire valide.
Informations complémentaires: Cela ne fonctionne pas non plus:
providers = apr_array_make(pool, 1, svn_auth_provider_object_t.sizeof);
svn_auth_provider_object_t* newSlot = cast(svn_auth_provider_object_t*) apr_array_push(providers);
svn_auth_get_simple_provider2(&newSlot, null, null, pool);
svn_auth_open(&auth_baton, providers, pool);
Alors que les règles sur ma théorie que les données ne va au bon endroit. Cependant, si je commente la ligne de commande du tableau et envoie le tableau vide, cela fonctionne correctement. Donc, cela ne pas segmentation fault:
providers = apr_array_make(pool, 1, svn_auth_provider_object_t.sizeof);
svn_auth_open(&auth_baton, providers, pool);
Je sais aussi qu'il est svn_auth_get_simple_provider2 pas parce que ce segfaults et ...
providers = apr_array_make(pool, 1, svn_auth_provider_object_t.sizeof);
svn_auth_provider_object_t* newSlot = cast(svn_auth_provider_object_t*) apr_array_push(providers);
svn_auth_get_ssl_server_trust_file_provider(&newSlot, pool);
svn_auth_open(&auth_baton, providers, pool);
De manière à ce que le contrôle segfault soit définitif, gdb version 7.2 devrait fonctionner avec D. Donc, si vous compilez avec '-gc' et que les dumps core sont activés, vous devriez être capable de voir ce qui cause le segfault en utilisant gdb. –
Je suis novice dans l'écriture de programmes qui se résument au langage machine. Donc, je ne suis pas familier avec gdb, j'essaie de l'utiliser mais je ne m'attendais pas à ce qu'il fonctionne bien avec D. Tout ce que j'ai compris jusqu'ici est de faire marche arrière. –
auto n'est pas un type. Cela permet d'inférer le type, puisque le compilateur sait quel type est renvoyé par la fonction. Le type ne peut pas être modifié, et vous pouvez trouver ce que c'est avec typeid (var). –