Прототип функции без дублирования параметров
От: -prus-  
Дата: 27.02.19 13:11
Оценка:
Подскажите плиз...
Вот если есть прототип функции, например:
int BlaBla(const std::string& str, std::uint32_t id, std::shared_ptr& ptr);

Есть ли какой-то механизм сделать, чтобы вот такое
using BlaBlaFunc = int(const std::string& str, std::uint32_t id, std::shared_ptr& ptr);

можно было без дублирования параметров сделать, т.е. что-то вроде
int BlaBla(const std::string& str, std::uint32_t id, std::shared_ptr& ptr);
using BlaBlaFunc = TURBO_UNREAL_MACROS_FUNC_PROTOTYPE(BlaBla);

У буста там ничего нету такого случайно?
С уважением,
Евгений
Re: Прототип функции без дублирования параметров
От: niXman Ниоткуда https://github.com/niXman
Дата: 27.02.19 13:14
Оценка:
Здравствуйте, -prus-, Вы писали:

using BlaBlaFunc = int(const std::string& str, std::uint32_t id, std::shared_ptr& ptr);
BlaBlaFunc *func_ptr = some_real_func;

?

либо опиши реальную ситуацию в которой тебе это понадобилось.

или ты хочешь получить сигнатуру имея реальную функцию?
пачка бумаги А4 стОит 2000 р, в ней 500 листов. получается, лист обычной бумаги стОит дороже имперского рубля =)
Отредактировано 27.02.2019 13:20 niXman . Предыдущая версия . Еще …
Отредактировано 27.02.2019 13:18 niXman . Предыдущая версия .
Отредактировано 27.02.2019 13:14 niXman . Предыдущая версия .
Re[2]: Прототип функции без дублирования параметров
От: -prus-  
Дата: 27.02.19 13:21
Оценка:
Здравствуйте, niXman, Вы писали:

X>
X>using BlaBlaFunc = int(const std::string& str, std::uint32_t id, std::shared_ptr& ptr);
X>BlaBlaFunc *func_ptr = some_real_func;
X>


Немного не то...
Например, чтобы можно было динамически из библиотеки:
int BlaBla(const std::string& str, std::uint32_t id, std::shared_ptr& ptr);
...
BlaBlaFunc func = dll_func_import("BlaBla");
С уважением,
Евгений
Re[3]: Прототип функции без дублирования параметров
От: niXman Ниоткуда https://github.com/niXman
Дата: 27.02.19 13:27
Оценка:
Здравствуйте, -prus-, Вы писали:

P>Например, чтобы можно было динамически из библиотеки:

P>
P>int BlaBla(const std::string& str, std::uint32_t id, std::shared_ptr& ptr);
P>...
P>BlaBlaFunc func = dll_func_import("BlaBla");
P>


тебе нужно получить имя функции в виде строки?
пачка бумаги А4 стОит 2000 р, в ней 500 листов. получается, лист обычной бумаги стОит дороже имперского рубля =)
Re: Прототип функции без дублирования параметров
От: sergii.p  
Дата: 27.02.19 13:36
Оценка: 6 (1) +1
Здравствуйте, -prus-, Вы писали:

что-то типа этого?

#include <iostream>
using namespace std;

int BlaBla(const std::string& str, std::uint32_t id){
    cout << "blabla\n";
}
using BlaBlaFunc = decltype(&BlaBla);

int main() {
    BlaBlaFunc func = &BlaBla;
    func("", 0);
    // your code goes here
    return 0;
}
Re[4]: Прототип функции без дублирования параметров
От: -prus-  
Дата: 27.02.19 13:38
Оценка:
Здравствуйте, niXman, Вы писали:

X>тебе нужно получить имя функции в виде строки?

Похоже я хреново сформулировал... Мне нужно получить указатель.
Есть библиотека .so. В ней функция, указатель на которую нужно получить динамически.
В header'e библиотеки сейчас:
int BlaBla(const std::string& str, std::uint32_t id, std::shared_ptr& ptr);
using BlaBlaFunc = int(const std::string& str, std::uint32_t id, std::shared_ptr& ptr);

Тут как бы получается список параметров два раза дублируется и если потом вдруг параметры поменяются, то можно забыть их поменять во второй строчке.
Хотелось бы просто поменяв прототип BlaBla, чтобы BlaBlaFunc также бы соответствовал новому прототипу, что-то типа:
int BlaBla(const std::string& str, std::uint32_t id, std::shared_ptr& ptr);
using BlaBlaFunc = TURBO_UNREAL_MACROS_FUNC_PROTOTYPE(BlaBla);

Ну а там дальше в коде, где используется библиотека:
BlaBlaFunc blaBlaFunc = dll_import_func(lib.so, "BlaBla");
ret = blaBlaFunc(...);
С уважением,
Евгений
Re: Прототип функции без дублирования параметров
От: Videoman Россия https://hts.tv/
Дата: 28.02.19 08:04
Оценка: 3 (1)
Здравствуйте, -prus-, Вы писали:

Не уверен что правильно понял, может это:
template<typename>
    class ModuleFunction;

    template<typename ReturnType, typename ...Args>
    class ModuleFunction<ReturnType(Args...)>
    {
    public:

        using FuncPtr = ReturnType (*)(Args...);

        ////////////////////////////////////////////////////////////////////////////////////////////
        // Construction/Destruction

        ModuleFunction(const ModuleFunction& that) = delete;
        ModuleFunction(ModuleFunction&& that) noexcept;
        ModuleFunction(string_t name, string_t funcName);
        ~ModuleFunction() noexcept;

        ////////////////////////////////////////////////////////////////////////////////////////////
        // Public methods

        void swap(ModuleFunction& that) noexcept;
        ModuleFunction& operator=(ModuleFunction that) noexcept;

        ReturnType operator()(Args... args) const;
        FuncPtr operator&() const;
        
    private:

        ////////////////////////////////////////////////////////////////////////////////////////////
        // Internal type definitions

        using native_handle_type = sys::native_handle_type;

        ////////////////////////////////////////////////////////////////////////////////////////////
        // Data members

        string_t m_name;                // Shared module name
        string_t m_funcName;            // Shared function name
        native_handle_type m_module;    // Shared module handle
        FuncPtr m_func;                 // Shared function address
    };

    ////////////////////////////////////////////////////////////////////////////////////////////////
    // Construction/Destruction

    template<typename ReturnType, typename ...Args>
    inline ModuleFunction<ReturnType(Args...)>::ModuleFunction(ModuleFunction&& that) noexcept
    :   m_libName(std::move(that.m_libName))
    :   m_funcName(std::move(that.m_funcName))
    ,   m_module(std::move(that.m_module))
    ,   m_func(std::move(that.m_func))
    {
        that.m_module = nullptr;
        that.m_func = nullptr;
    }

    template<typename ReturnType, typename ...Args>
    inline ModuleFunction<ReturnType(Args...)>::ModuleFunction(string_t name, string_t funcName)
    :   m_name(std::move(name))
    ,   m_funcName(std::move(funcName))
    ,   m_module(sys::ModuleLoad(m_name))
    ,   m_func(reinterpret_cast<FuncPtr>(sys::ModuleFunc(m_module, m_funcName)))
    {
    }

    template<typename ReturnType, typename ...Args>
    inline ModuleFunction<ReturnType(Args...)>::~ModuleFunction() noexcept
    {
        sys::ModuleUnload(m_module);
    }

    ////////////////////////////////////////////////////////////////////////////////////////////////
    // Public methods
       
    template<typename ReturnType, typename ...Args>
    inline void ModuleFunction<ReturnType(Args...)>::swap(ModuleFunction& that) noexcept
    {
        using v2::swap;

        swap(m_name, that.m_name);
        swap(m_funcName, that.m_funcName);
        swap(m_module, that.m_module);
        swap(m_func, that.m_func);
    }

    ////////////////////////////////////////////////////////////////////////////////////////////////
    template<typename ReturnType, typename ...Args>
    inline ModuleFunction<ReturnType(Args...)>& ModuleFunction<ReturnType(Args...)>::operator=(ModuleFunction that) noexcept
    {
        swap(that);

        return *this;
    }

    ////////////////////////////////////////////////////////////////////////////////////////////////
    template<typename ReturnType, typename ...Args>
    inline ReturnType ModuleFunction<ReturnType(Args...)>::operator()(Args... args) const
    {
        typedef ReturnType(__cdecl* Func)(Args...);

        if (m_func == nullptr) {

            const string_t& error = Format("Fail to call function \"{0}\". Module \"{1}\" not properly loaded.", m_funcName, m_name);
            throw v2::Exception(error);
        }

        return reinterpret_cast<Func>(m_func)((std::forward<Args>(args))...);
    }

    ////////////////////////////////////////////////////////////////////////////////////////////////
    template<typename ReturnType, typename ...Args>
    inline typename ModuleFunction<ReturnType(Args...)>::FuncPtr ModuleFunction<ReturnType(Args...)>::operator&() const
    {
        return m_func;
    }

Можно использовать так:
static const ModuleFunction<int(int, int)> sumfunc("some.dll", "sumfunc");
//... Где-то в коде
int a = sumfunc(5, 5);

Это оно?
Re[2]: Прототип функции без дублирования параметров
От: -prus-  
Дата: 28.02.19 08:17
Оценка:
Здравствуйте, Videoman, Вы писали:

V>Здравствуйте, -prus-, Вы писали:


V>Не уверен что правильно понял, может это:

V>Это оно?

Не совсем, мне нужно было не дублировать прототип, а у тебя тут все равно нужно:
static const ModuleFunction <int(int, int)> sumfunc("some.dll", "sumfunc");

Нужно было вот как тут
Автор: sergii.p
Дата: 27.02.19
уже ответили.
Но спасибо все равно, что заморочился.
С уважением,
Евгений
Re[3]: Прототип функции без дублирования параметров
От: Videoman Россия https://hts.tv/
Дата: 28.02.19 09:02
Оценка: +1
Здравствуйте, -prus-, Вы писали:

P>Не совсем, мне нужно было не дублировать прототип, а у тебя тут все равно нужно:

В принципе, можно и не дублировать :
static const ModuleFunction <decltype(sumfunc)> sumfunc("some.dll", "sumfunc");
 
Подождите ...
Wait...
Пока на собственное сообщение не было ответов, его можно удалить.