Я пишу программу в D, которая использует svn, и я наткнулся на то, что не могу понять, как преобразовать в синтаксис D. Я сделал удар, но это не так.Добавить массив, используя apr_array_push в D
Пример того, что я пытаюсь сделать в 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);
Насколько я знаю, этот код работает отлично. Я нашел несколько примеров, сделанных почти точно так же. Вот моя попытка скопировать это в 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);
Это бросает Сегментация Fault на svn_auth_open. Мое лучшее предположение заключается в том, что содержимое провайдера не заканчивается указателем, хранящимся в newSlot. И я не знаю, почему это так.
Дополнительный код:
/// 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;
}
Мое предположение, что происходит выдаёт ошибку сегментации в APR_ARRAY_IDX. Все остальное имеет действительный адрес памяти.
Дополнительная информация: Это не работает либо:
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);
Так что исключает мою теорию о том, что данные не собирается в нужном месте. Однако, если я прокомментирую строку push массива и просто отправлю массив пустым, он отлично работает. Таким образом, это не сегментации:
providers = apr_array_make(pool, 1, svn_auth_provider_object_t.sizeof);
svn_auth_open(&auth_baton, providers, pool);
Я также знаю, что это не svn_auth_get_simple_provider2, потому что это, а также ошибки сегментации ...
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);
В качестве способа определения пути segfault версия gdb 7.2 должна работать с D. Итак, если вы компилируете с помощью '-gc' и включаете основные дампы, то вы должны уметь видеть, что вызывает segfault, используя GDB. –
Я новичок в написании программ, которые скомпилируются до машинного языка. Поэтому я не знаком с gdb, я пытаюсь использовать его, но он не ожидал, что он будет хорошо работать с D. Все, что я догадался сделать до сих пор, - это откат. –
авто не тип. Он позволяет вывести тип, поскольку компилятор знает, какой тип возвращается из функции. Тип не может быть изменен, и вы можете узнать, что это такое с typeid (var). –