2015-07-02 2 views
1

У меня есть библиотека C, которая принимает непрозрачные указатели в заголовке.Вызов функции extern C, вызванной с void *

Вот мой C заголовок

typedef void* dbaxRange_p; 
typedef void* dbaxFunction_p; 

extern "C" { 
    // ... lots of other methods... 
    EXPORT dbaxRange_p range_d(const double value); 
    EXPORT void add_param(dbaxFunction_p func, dbaxRange_p arg); 
    EXPORT dbaxFunction_p dbax_function(const char* name, const int num_params); 
    // Call method taking void* 
    EXPORT dbaxRange_p call(dbaxFunction_p func); 
} 

Вот мой D интерфейс CDbax.d:

extern (C): 
alias void *dbaxFunction_p; 
alias void *dbaxRange_p; 

extern (C) { 
dbaxRange_p range_d(double value); 
void add_param(dbaxFunction_p func, dbaxRange_p arg); 
dbaxFunction_p dbax_function(const char *name, int num_params); 
dbaxRange_p call(dbaxFunction_p func); 
} 

И вот мой вызов функции

class Dbax { 
    // ... 
    dbaxFunction_p func_; 
    this(string name) { 
     func_ = dbax_function(std.string.toStringz(name),0); 
    } 
    Dbax add(double val) { 
     auto rng = range_d(val); 
     add_param(func_,rng); 
     return this; 
    } 
    dbaxRange_p call() { 
     return call(cast(dbaxFunction_p) this.func_); 
    } 
} 

main.d

import CDbax; 
void test() 
{ 
    auto res = new CDbax.Dbax("GetVersionNumber").add(0.24).call(); 
} 

Но я получаю эту ошибку: -

CDbax.d(113): Error: function CDbax.Dbax.call() is not callable using argument types (void*) 

Update Ответ в том, что есть пространство имен столкновение. Он взял вызов C FFI, а не функцию вызова класса Dbax. Я задам следующий вопрос о том, почему

ответ

3

Это просто случай, когда он пытается вызвать метод call вместо глобальной функции. (Кстати, вы уверены, что функция C называется call, и это не макрос? Очень редко для функции C есть такое голое имя.)

В любом случае, когда вы находитесь внутри класса, это всегда смотрит на класс сначала для членов, а D - , а не перегрузка между единицами, если вы специально не попросите его на alias innerName = full.outer.name; Объяснение почему здесь: http://dlang.org/hijack.html в основном это так, что добавление глобальной функции позже не нарушает класс путем введения новая, запутанная перегрузка. Автор класса должен быть в состоянии сосредоточиться на источнике только класса, не беспокоясь о новом глобальном, написанном другим программистом в модуле далеко, далеко, что делает ее код более запутанным.

Самый простой способ решить эту проблему в вашем случае использовать полное имя, или, по крайней мере, глобальный масштаб оператор в вызове:

return call(cast(dbaxFunction_p) this.func_); // before 

    return .call(cast(dbaxFunction_p) this.func_); // after 

Ведущая точка означает «смотреть его в Топ- уровневое пространство имен ". (Кстати, подобным образом, вы можете явно использовать this.call, когда вы хотите, чтобы смотреть только на this.)

Когда эти вещи приходят, вы также можете предварять имя модуля неоднозначность, если вы предпочитаете, чтобы быть еще более четко:

foo.bar.call(); // looks in foo.bar 
Смежные вопросы